news.utdallas.edu!tamsun.tamu.edu!cs.utexas.edu!zaphod.mps.ohio-state.edu!sdd.hp.com!network.ucsd.edu!deadmin.ucsd.edu!heart3.ucsd.edu!bense Mon Mar  8 19:44:53 CST 1993
Article: 1157 of comp.infosystems.gopher
Xref: feenix.metronet.com comp.infosystems.gopher:1157
Path: feenix.metronet.com!news.utdallas.edu!tamsun.tamu.edu!cs.utexas.edu!zaphod.mps.ohio-state.edu!sdd.hp.com!network.ucsd.edu!deadmin.ucsd.edu!heart3.ucsd.edu!bense
From: bense@heart3.ucsd.edu (Booker C. Bense)
Newsgroups: comp.infosystems.gopher
#Subject: Re: Does a gopher "Editor" exist?
Message-ID: <2504@deadmin.ucsd.edu>
Date: 6 Mar 93 03:44:40 GMT
References: <1993Mar1.090258.1@fennel.cc.uwa.oz.au>
Sender: news@deadmin.ucsd.edu
Organization: San Diego Supercomputer Center @ UCSD
Lines: 362

In article <1993Mar1.090258.1@fennel.cc.uwa.oz.au> d_rindos@fennel.cc.uwa.oz.au writes:
>At the present time we are busy with the creation of anthro-gopher 
>which will eventually be a world-wide service for the use of the 
>anthropological community.  Given the size of the task before us one 
>of our greatest needs would be a "user-friendly" interface for editing 
>files and menus (by user-friendly, I mean something that could be used 
>by, for example, a Departmental secretary who has NO training in 
>programming).  
>

- Well, this is not an editor by any means, but I think you might 
find it a handy first step. It is set up for the way I run my gopher
server, but should be easy to modify. 

Instgopher is a perl script developed to make the process of
installing docs into gopher easier for non-unix types. It is based on
several assumptions.

1. There is a group called $gopher_group for people who maintain
the gopher-data and the user that runs gopherd is part of this group.

2. All documents are installed in single repository with symbolic
links from the gopher-data area into the repository. I have gopher
set up this way to make waisindexing easier. 

instgopher will walk you down a gopher tree through the actual menu
items that appear to the client. In effect it is a very simple 
client that only knows about directories or type 1 gopher items. 
Once you choose a directory to install in , it will ask you for 
the menu name and the numbering order. It tries to be smart about
not overwriting data. It sets up the .cap directories and makes
sure everything is $gopher_group readable/writable. 

- It will not allow the user to create a new
directory, gopher links or any of the other whizzy stuff
gopher does. I consider this a feature not a bug! 

- If you have any comments/questions about this please send
email to :

benseb@sdsc.edu 

------cut-here------------------------------------------------
#!/usr/local/apps/perl/bin/perl
# This script installs a file in gopher. 
#
require 'sys/socket.ph';

sub dokill {
    kill 9,$child if $child;
}


sub Opengopher {

   local($them,$port) = @_;	
   $them = 'localhost' unless $them;

   $AF_INET = 2;
   $SOCK_STREAM = 1;

   $SIG{'INT'} = 'dokill';

   $sockaddr = 'S n a4 x8';

   chop($hostname = `hostname`);

   ($name,$aliases,$proto) = getprotobyname('tcp');
   ($name,$aliases,$port) = getservbyname($port,'tcp')
      unless $port =~ /^\d+$/;;
   ($name,$aliases,$type,$len,$thisaddr) = gethostbyname($hostname);
   ($name,$aliases,$type,$len,$thataddr) = gethostbyname($them);

   $this = pack($sockaddr, $AF_INET, 0, $thisaddr);
   $that = pack($sockaddr, $AF_INET, $port, $thataddr);

   # Make the socket filehandle.
   socket(S, $AF_INET, $SOCK_STREAM, $proto) || die $!;

   # Give the socket an address.
   bind(S, $this) || die $!;

   # Call up the server.
   connect(S,$that) || die $!;

   # Set socket to be command buffered.
   select(S); $| = 1; select(STDOUT);

}


sub ReadGopher {

   local($Obj,$ObjName,$Host,$Path,$Port);
   while (<S>) {
      chop;
      chop;
      next if /^\.$/;
      ($ObjName, $Path, $Host, $Port) = split('\t', $_, 6);
      $Obj  = substr($ObjName, 0, 1);

      next if ($Obj != 1);
      if ( $Path ) {
         push(@Items,$Path);
         $ObjName =~ s/^1//; # Just want to strip off the 1 not rest
         $Names{$Path}=$ObjName;
      }
   }
   close(S);
   return(*Items,%Names);

}


sub get_list_of_items {

# Get All the dirs to install into 

    local($Path) = @_ ; 
    
   &Opengopher($CurrentHost,$Port);

   print S "$Path\n";

   (*List,%Names) = &ReadGopher;

   return(*List,%Names);

}

sub gopher_perm {
    local( $file ) = @_ ; 
    chmod( 0664, "$file"  ) || die "Couldn't chmod $file \n" ; 
    system("/bin/chgrp $gopher_group $file") && 
	die "Couldn't chgrp $gopher_group $file \n" ; 
} 

sub install_in_gopher {
    local( $data , $path , $menu ,$number ) = @_ ; 
# get tail of $data
    @datapath = split(/\//,$data);
    $datatail = pop(@datapath);
    $data_real = "$real_gopher/$datatail";
    $data_link = "$path/$datatail";
    @data_time = localtime ; 
    ( $day,$month,$year ) = ($data_time[3],$data_time[4],$data_time[5]); 
#
#	First move $data to general store area. 
#
    if ( ! -e $data_real ) {
	# this look wrong but system returns 0 on success. 
	system("/bin/cp $data $data_real") && 
	    die "Cp $data $data_real failed\n";
	&gopher_perm ( $data_real ) ; 
    } elsif ( -w $data_real ) {
	print "Document $datatail already is installed. \n";
	print "Type r to replace it: l to create a new link to it: "; 
	$choice = <STDIN> ; 
	if ( $choice =~ m/^[rR]/ ) {
	    # move old file 
	    rename( $data_real , "$data_real.$day\:$month\:$year" ) 
		|| die "Rename of $data_real failed \n";
	    # this look wrong but system returns 0 on success. 
	    system("/bin/cp $data $data_real") && 
		die "Cp $data $data_real failed\n";
	    &gopher_perm ( $data_real ) ; 
	    &gopher_perm ( "$data_real.$day\:$month\:$year" ); 
	} 

    } else {
	print "You do not have write permission on $data_real.\n" ; 
	print "Contact $gopher_admin to install this document. \n"; 
	return ; 
    }
#
# Now create the symbolic link in gopher-data 
#
    if ( ! -e $data_link  ) {
	# this looks wrong but system returns 0 on success. 
	symlink($data_real,$data_link)  ||
	    die "ln  $data_real $data_link failed\n"; 
    } elsif ( -l $data_link && -w $data_link ) {
	unlink($data_link ) || 
	    die "rm $data_link failed\n"; 
	symlink($data_real,$data_link)  ||
	    die "ln  $data_real $data_link failed\n"; 

    } else {
	print "You do not have write permission on $data_link \n" ; 
	print "or $data_link is not a symbolic link. \n" ; 
	print "Contact $gopher_admin to install this document. \n"; 
	return ; 
    }
#
#   Now create .cap links
#
    $capdir = "$path/.cap"; 
    if ( ! -d $capdir ) { 
	# This is createing capdir with 400 perms for unknown reasons
	mkdir( $capdir, 0775 ) || die "Could not make .cap directory! \n"; 
	system("/bin/chgrp $gopher_group $capdir") 
	    && die "Could not chgrp .cap directory! \n"; 
    } elsif ( ! -w "$path/.cap" ) {
	print "You do not have write permission on $capdir . \n" ; 
       	print "Contact $gopher_admin to install this document. \n"; 
	return ;
    }
    $capfile = "$path/.cap/$datatail"; 
    if (  -e $capfile ) {
	unlink( $capfile ) || die "Could not rm $capfile \n"; 
    }
    open(CAP,">$capfile"); 
    print CAP "Name=$menu\n" ;
    print CAP "Numb=$number\n"; 
    close(CAP); 
    &gopher_perm($capfile); 
}


############## MAIN #################################################
# This  script will ask a user where he wants the gopher item
# to appear and do the correct things. 
#
######################################################################
# Variables
# Gopher server
$CurrentHost = "bar.foo.bar";
$Port = 70;
$Path = "\n";
# Unix file system home of gopher
$gopherhome = '/gopherhome';
$real_gopher= $gopherhome . "/FOONLYdocs" ;
$gopher_data= $gopherhome . "/gopher-data";
$gopher_admin = 'gopherdude@foo.bar'; 
$gopher_group = 'gopher' ; 

umask( 002 ) ; 
#
# Get data from user 
#
if ( scalar(@ARGV) > 0 ){
    $datafile = $ARGV[0] ; 
    if ( ! -f $datafile ) {
	print "Usage:  $0 doc_to_install [gopher_path]\n";
	print " doc_to_install is the name of the file\n";
	print " gopher_path is the gopher locator of where to install it\n";
	print " Both of these are optional \n"; 
	$datafile = 0; 
    }
}
    
if ( scalar(@ARGV) > 1 ) {
    $inst_path = "$gopher_data/$ARGV[1]"; 
    if ( ! -d $inst_path ) {
	print "Sorry, $inst_path is not an area in gopher...";
	$inst_path = 0; 
    }
}
#
# If we don't have a datafile get one. 
#
while ( ! $datafile ) {
    print "Enter the name of the doc to install: " ;
    chop($datafile = <STDIN>);
    if ( ! -f $datafile ) {
	print "Sorry $datafile was not found\n"; 
	$datafile = 0 ; 
    }
}
#
# If we don't have an instpath get one, might need to descend tree. 
#
$done = 0; 
while ( ! $done ) {
# Get list of items
    (*ListOfItems,%RealNames) = &get_list_of_items($Path) ;

    while ( ! $inst_path ) {
	print "Choices are :\n" ; 
	$i = 1; 
	foreach (@ListOfItems) {
	    print "\[$i\]     $RealNames{$_}\n";
	    ++$i ; 
	}
	print "Enter the number of the directory to install in\[1\]: " ;
	$choice = <STDIN> ; 
	if ( $choice > 0 && $choice <= scalar(@ListOfItems) ){

	    $inst_path = $ListOfItems[--$choice]; 
            $Path = $inst_path ; 
	    $inst_path =~ s/^1// ; 
            $top_menu = $RealNames{--$choice} ; 
	    $inst_path = $gopher_data . $inst_path; 
	    if ( ! -d $inst_path ) {
		print "Sorry $inst_path was not found\n"; 
		$inst_path = 0 ; 
	    } 
	} else {
	    print "$choice is not a valid choice\n";
	}
    }
    print "Do you want to descend further?\[y/n] :" ; 
    $choice = getc ; 
    if ( $choice ne 'y' ) {
	$done = 1; 
    } else { 
	$inst_path = 0 ; # reset inst_path, List_of_Items and RealNames
	reset 'L','R' ; 
	 
    }
}
# to clear out STDIN
$choice = <STDIN> ; 
#
# Now get Menu Name :  
#
$done = 0; 
while ( ! $done ) {
	print "Now choose the name for the gopher menu\n";
        print "Spaces are fine but try to keep it under 45 chars\n";
	print "Enter the gopher menu item string:\n " ; 
        print "1      10       20       30       40   45\n"; 
	$menu = <STDIN> ;
	chop( $menu);  
	$number = 0 ; 
	while ( ! $number ) {
	    print "Enter the menu number 1=top :";
	    $number = <STDIN>;
	    chop( $number); 
	    if ( $number < 1 ) {
		$number = 0 ; 
		print "$number is not a valid number. Try again.\n"; 
	    }
	}
	print "$datafile will appear in $top_menu as \n$menu\n" ; 
	print "Type y install : m to change menu name : n to quit: ";
	$choice = getc ;
	if ( $choice eq  'y' ) {
		$done = 1; 	
	} elsif ( $choice ne 'm' ) {
		exit ; 
	}
	$choice = <STDIN> ; # to clear out <STDIN> 
}

&install_in_gopher ( $datafile , $inst_path , $menu , $number) ; 

exit ; 
print "Do you want to install another document ? [y/n] : " ; 
$choice = getc ; 
if ( $choice eq 'y' ) {
# reset variables and go to start 


} 






exit;


