From: kjenks@gothamcity.jsc.nasa.gov
Subject: Re: Automated FTP?
Originator: kjenks@gothamcity
Keywords: getit
Organization: NASA/JSC/GM2, Space Shuttle Program Office
Date: Sat, 19 Dec 1992 17:18:40 GMT

I wrote a little program called "getit" which is also available for
anonymous FTP (of course!) at
  export.lcs.mit.edu:contrib/getit.tar.Z

Here's the README, then the source code.  Enjoy, and tell all of your
friends to post their anon-FTP file references in "getit" format!

-- Ken Jenks, NASA/JSC/GM2, Space Shuttle Program Office
      kjenks@gothamcity.jsc.nasa.gov  (713) 483-4368

     "We at NASA develop cutting-edge technology for our aeronautics and
      space programs.  We view technology transfer as a way of life.  
      It's one of our top priorities." -- Daniel S. Goldin, NASA Administrator

-------------------------------------------------------------------
"getit" is a short C program which uses anonymous FTP to retrieve a
file specified on the command line.  To use it, run getit as either:
   getit host:path/file 
-or-
   getit path/file@host

For example, this file is available via anonymous FTP using
   getit contrib/getit.tar.Z@export.lcs.mit.edu
which can also be written as
   getit export.lcs.mit.edu:contrib/getit.tar.Z

To "make" the UNIX version of getit, simply use "cc -o getit getit.c"

The MS-DOS version, getitexe.exe, uses FTP Software's PC/TCP network
drivers.  It assumes that the "FTP.EXE" program is in the DOS path.  To
recompile getitexe.exe, you'll need Borland's Turbo C.  Note that the
password getitexe.exe uses for anonymous FTP SHOULD be your e-mail ID,
but that will have to be hard-coded in this program.  When you get this
loaded on your PC, you'll probably want to rename it to "getit.exe" so
it's easier to type.  As always, make sure you check for viruses.
Practice safe downloading.

Ken Jenks
Space Shuttle Program Office
NASA Lyndon B. Johnson Space Center
Houston, Texas
(713) 483-4368
kjenks@gothamcity.jsc.nasa.gov

-------- Begin source code --------------------------------------------
/* 
 *  getit.c (UNIX version)
 *        - use anonymous FTP to get a file named on the command line
 *        - file reference formats: (1) host:path/file, (2) path/file@host.
 *
 *        - written by NASA/JSC/GM2/Ken Jenks
 *        - send comments to kjenks@gothamcity.jsc.nasa.gov
 *
 */
#include <stdio.h>
#include <string.h>

#ifndef lint
static char rcsid[] = "$Header: getit.c,v 1.0 92/08/18 13:08:50 kcj Exp $";
#endif

char *status_message;
char *full_ref;
char host_name[2048],path_name[2048],file_name[2048],mail_name[2048];

extern void exit();
extern char *malloc(), *index(), *rindex();
extern int system();

int main(argc, argv)
int argc;
char *argv[];
{
  FILE *fp;

  char *p, *b, status_msg_buff[2048], *program;
  int dir, ascent, descent, error_level;

  status_message = status_msg_buff;
  *status_message = '\0';

  program = argv[0];

  error_level = 0; /* Assume error code is 0 unless errors occur */

  /* 
   * If there is no file reference on command line, use false reference
   * so we give usage & exit
   */
  if(argc == 2) {
    full_ref=strncpy(malloc(strlen(argv[1])+1),argv[1],strlen(argv[1]));
    full_ref[strlen(argv[1])]='\0';
  }
  else
    full_ref = "(none)";

#ifdef DEBUG
  fprintf(stderr,"%s: full reference is %s\n",program,full_ref);
#endif

  /* Now, I'll determine the host, path and file names from the
   * full reference.
   */

  /* Case 1: full_ref = "host:path/file"
   */
  if (index(full_ref,':')) {

    strncpy(host_name,full_ref,index(full_ref,':')-full_ref);
    strcpy(path_name,index(full_ref,':')+1);

    /* Case 1a: Either path has a / in it or not.
    */
    if(rindex(path_name,'/')) {
      strcpy(file_name,rindex(path_name,'/')+1);
      *rindex(path_name,'/') = '\0';

    /* Case 1b: No / in path 
    */
    } else {
      strcpy(file_name, path_name);
      strcpy(path_name, ".");
    }

  /* Case 2: full_ref = "path/file@host"
  */
  } else if (index(full_ref,'@')) {

    strncpy(path_name,full_ref,index(full_ref,'@')-full_ref);
    strcpy(host_name,index(full_ref,'@')+1);

    /* Case 2a: Either path has a / in it or not.
    */
    if(rindex(path_name,'/')) {
      strcpy(file_name,rindex(path_name,'/')+1);
      *rindex(path_name,'/') = '\0';

    /* Case 2b: No / in path 
    */
    } else {                   /* No / in path */
      strcpy(file_name, path_name);
      strcpy(path_name, ".");
    }

  /* Case 3: full_ref = none of the above
  */
  } else {
    sprintf(status_message,
      "Error: can't interpret file reference:\n%s\n\n\"%s\" provides rapid access to files using anonymous FTP.\nUsage:\n   %s host:path/file\n-or-\n   %s path/file@host\n",
      full_ref,program,program,program);
    error_level = 1;
    goto show_status;
  }

  /* Remove extraneous CR from end of strings
  */
  if(strlen(file_name))
    if(file_name[strlen(file_name)-1] == 10)
      file_name[strlen(file_name)-1] = '\0';

  if(strlen(path_name))
    if(path_name[strlen(path_name)-1] == 10)
      path_name[strlen(path_name)-1] = '\0';

  if(strlen(host_name))
    if(host_name[strlen(host_name)-1] == 10)
      host_name[strlen(host_name)-1] = '\0';

  /* Perform the command to get user's e-mail ID and capture the results
  */
  system("echo `whoami`@`hostname`.`domainname` > getit_mail_file");

  /* Read e-mail ID for use as password in anonymous FTP
  */
  if((fp = fopen("getit_mail_file","r")) == NULL) {
    fprintf(stdout, "Warning: can't determine e-mail ID for password");
    strcpy(mail_name,"can't-find-e-mail-ID");
  } else
    fscanf(fp,"%s",mail_name);
  strcpy(mail_name+strlen(mail_name),"(getit)");

#ifdef DEBUG
  fprintf(stderr,"  host: %s\n",host_name);
  fprintf(stderr,"  path: %s\n",path_name);
  fprintf(stderr,"  file: %s\n",file_name);
  fprintf(stderr,"  pswd: %s\n",mail_name);
#endif

  /* Open scratch file to hold FTP commands
  */
  if((fp = fopen("getit_scratch_file","w")) == NULL) {
    sprintf(status_message,"Error: can't open scratch file %s",
      "getit_scratch_file");
    error_level = 2;
    goto show_status;
  }

  /* Build the commands needed to execute the anonymous FTP
  */
  fprintf(fp,"#! /bin/sh\n");
  fprintf(fp,"/bin/echo \"Getting file %s from path %s at host %s...\"\n",
    file_name,path_name,host_name);
  fprintf(fp,"/usr/ucb/ftp -inv << EOF\n");
  fprintf(fp,"open %s\n",host_name);
  fprintf(fp,"\n");
  fprintf(fp,"user anonymous %s\n",mail_name);
  fprintf(fp,"binary\n"); /* Turn binary ON for all transfers */
  fprintf(fp,"prompt\n"); /* Turn prompt OFF for possible mget */
  if((*path_name != '.') || (strlen(path_name) != 1))
    fprintf(fp,"cd %s\n",path_name);

  /* Do either mget or get, depening on existance of '*' in file_name
  */
  if(index(file_name,'*'))
    fprintf(fp,"mget %s\n", file_name); 
  else
    fprintf(fp,"get %s\n", file_name); 

  fprintf(fp,"quit\n");
  fprintf(fp,"EOF\n");
  fclose(fp);

  /* Perform the FTP and capture the results
  */
  system("sh getit_scratch_file > getit_error_file");

  /* Read any resulting error messages
  */
  if((fp = fopen("getit_error_file","r")) == NULL) {
    sprintf(status_message,"Warning: can't read error file %s",
      "getit_error_file");
    error_level = 3;
    goto show_status;
  }

  status_message = status_msg_buff;
  while(feof(fp) == 0)
    *(status_message++) = fgetc(fp);
  *(--status_message) = '\0';
  status_message = status_msg_buff;

  fclose(fp);

show_status:
 
  system("rm -f getit_*_file > /dev/null");

  /* If there is no message to be displayed, exit quietly. 
   */
  if(status_message)
    if(strlen(status_message))
      fprintf(stderr,"%s\n",status_message);
  exit(error_level);
}
Newsgroups: comp.sys.sun.misc