home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / t / tel2305s.zip / FTP / FTPBIN.C
C/C++ Source or Header  |  1992-03-24  |  86KB  |  2,456 lines

  1. /*
  2. *  User FTP
  3. *  6/8/87
  4. ****************************************************************************
  5. *                                                                          *
  6. *      by Tim Krauskopf and Swami Natarajan                                *
  7. *             Microsoft port by Heeren Pathak                               *
  8. *                                                                          *
  9. *      National Center for Supercomputing Applications                     *
  10. *      152 Computing Applications Building                                 *
  11. *      605 E. Springfield Ave.                                             *
  12. *      Champaign, IL  61820                                                *
  13. *                                                                          *
  14. *                                                                          *
  15. ****************************************************************************
  16. *
  17. */
  18.  
  19. /*
  20.  *Thanks to Jyrki Kuoppala(jkp@hutcs.hut.fi) for the basis of changes for
  21.  * MSC 5.1 
  22. */
  23.  
  24. #define FTPMASTER
  25.  
  26. #ifdef __TURBOC__
  27. #include "turboc.h"
  28. #endif
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <fcntl.h>
  32. #include <ctype.h>
  33. #include <sys/types.h>
  34. #include <sys/stat.h>
  35. #include <signal.h>
  36. #include <time.h>
  37. #include <io.h>
  38. #include <errno.h>
  39. #include <string.h>
  40. #include <conio.h>
  41.  
  42. #ifdef    MSC
  43. #define    O_RAW O_BINARY
  44. #include <dos.h>
  45. #ifndef _TURBOC_
  46. #include <direct.h>
  47. #endif
  48. #include <malloc.h>
  49. #endif
  50.  
  51. #ifdef MEMORY_DEBUG
  52. #include "memdebug.h"
  53. #endif
  54. #include "nkeys.h"
  55. #include "hostform.h"
  56. #include "whatami.h"
  57. #include "ftppi.h"              /* list of commands, help strings */
  58. #include "defines.h"
  59. #include "vidinfo.h"
  60. #include "externs.h"
  61.  
  62. #define FASCII  0
  63. #define FIMAGE  1
  64. #define HFTP   21
  65.  
  66. #define FALSE        0
  67. #define TRUE        1
  68. #define SUCCESS        2
  69. #define HAVEDATA    4
  70. #define ERROR      -1
  71. #define NONE       -2
  72. #define ABORT       -3
  73. #define INCOMPLETE -4
  74. #define AMBIGUOUS  -5
  75.  
  76. int xp=0,                    /* general pointer */
  77.     towrite=0,                /* file transfer pointer */
  78.     len=0,                    /* file transfer length */
  79.     ftpnum,                    /* current command port */
  80.     ftpdata=-1,                /* current data port */
  81.     ftpfh,                    /* file handle for ftp */
  82.     ftpstate=0,                /* state for background process */
  83.     fcnt=0,                 /* counter for ftpd */
  84.     ftpfilemode=0,            /* file open mode for transfer */
  85.     foundbreak=0,            /* cntrl-break pending */
  86.     connected=0,            /* not connected */
  87.     debug=0,                /* debug level */
  88.     bypass_passwd=0,        /* whether to bypass the password check */
  89.     hash=0,                    /* hash mark printing */
  90.     sendport=1,                /* to send ports or not */
  91.     verbose=1,                /* informative messages */
  92.     redirect=1,                /* check for ouput redirection */
  93.     bell=0,                    /* sound bell */
  94.     autologin=1,            /* login on connect */
  95.     prompt=1,                /* check on multiple commands */
  96.     tempprompt=0,            /* temp var for Yes/No/All/Quit convenience */
  97.     glob=1,                    /* expand wildcards */
  98.     slashflip=1,            /* change \ to / */
  99.     capture=0,                /* capture data or not */
  100.     usemore=0,                /* use |more */
  101.     numlines=24,            /* number of lines for |more */
  102.     lineslft=24,            /* number of lines left for |more */
  103.     ttypass=0,                /* use interactive for password */
  104.     fromtty=1,                /* default input from tty */
  105.     f_enter_login=FALSE,    /* noninteractive but ask for user and pass */
  106.     display_init=FALSE,        /* TRUE if title line has been given */
  107.     scrsetup=0,                /* FALSE if need to clear screen */
  108.     dos_color;                /* storage for the DOS color setup */
  109.  
  110. FILE *fromfp=NULL;            /* file pointer for input */
  111. unsigned int curftpprt=0;    /* port to use */
  112. unsigned char destname[50]={0,0},    /* who to connect to */
  113.     s[550],                    /* temporary string */
  114.     path_name[_MAX_DRIVE+_MAX_DIR],        /* character storage for the path name */
  115.     captlist[2001],            /* response string */
  116.     ftpcommand[200];        /* command to execute */
  117. char printline[2001];        /* line to display */
  118.  
  119. struct config def;
  120.  
  121. char *config;
  122.  
  123. #ifdef _TURBOC_
  124. int use_mouse=0;
  125. #endif
  126.  
  127. #ifdef _TURBOC_
  128. #define BUFFERS 10000        /* size of buffer */
  129. #else
  130. #define BUFFERS 20000        /* size of buffer */
  131. #endif
  132. #define READSIZE 256        /* how much to read */
  133.  
  134. static unsigned char xs[BUFFERS+10];    /* buffer space for file transfer */
  135.  
  136. long start=0L,                /* timing var */
  137.     lengthfile=0L;            /* length of current file for transfer */
  138.  
  139. /* function prototypes for local functions */
  140. int main(int argc,char *argv[]);
  141. static char *stpblk(char *ch);
  142. static void breakstop(void );
  143. static unsigned int ftpport(void );
  144. static char *stptok(char *p,char *toword,int len,char *delim);
  145. static void nputs(char *line);
  146. static int printerr(void );
  147. static int ftppi(char *command);
  148. static int putstring(char *string);
  149. static int ftpgets(char *s,int lim,int echo);
  150. static int ftpdo(char *s,char *ofile);
  151. static int checkevent(void );
  152. static void nputchar(char ch);
  153. static int dumpcon(int cnum);
  154. static void telnet(int cnt);
  155. static int getword(char *string,char *word);
  156. static int finduniq(char *name,char *list[],int listsize);
  157. static int checkoredir(char *command,char *filename,int slashflip);
  158. static void flip_slashes(char *command,char *filename);
  159. static void getdir(int drive,char *path);
  160. static int ftpreplies(int cnum,int *rcode);
  161. static int getnname(char *string,char *word);
  162. static int rgetline(int cnum);
  163. static void userftpd(void );
  164. int numrows(void);
  165. void give_args(void);
  166. int domore(void);
  167. static char *check_file_name (char *in_fname, char *out_fname);
  168.  
  169. /************************************************************************/
  170. /* main-main procedure.  Displays opening message, parses arguments,
  171. /*      initializes network, reads user commands and executes them, and
  172. /*      cleans up.
  173. /************************************************************************/
  174. main(int argc,char *argv[])
  175. {
  176.     int i,c;
  177.     static char Configfile[50]="config.tel";
  178.     static char fromfile[20]="";
  179.  
  180.     /* Initialize the video configuration, and retrieve it */
  181.     initvideo();
  182.     getvconfig(&tel_vid_info);
  183.  
  184.     n_window(0,0,tel_vid_info.rows,tel_vid_info.cols);   /* to correctly handle non standard screen sizes */
  185. #ifdef __TURBOC__
  186.     fnsplit(argv[0],path_name,s,captlist,printline);   /* split path up */
  187. #else
  188.     _splitpath(argv[0],path_name,s,captlist,printline); /* split the full path name of telbin.exe into it's components */
  189. #endif
  190.     strcat(path_name,s);    /* append the real path name to the drive specifier */
  191.  
  192.     config=getenv("CONFIG.TEL");
  193.     if(config)
  194.         strcpy(Configfile,config);
  195.  
  196.     destname[0]='\0';        /* destination unknown */
  197.  
  198.     for(i=1; i<argc; i++) {     /* parse arguments */
  199.         if(argv[i][0]=='-' || argv[i][0]=='/') {
  200.             switch(tolower(argv[i][1])) {
  201.                 case 'r':        /* turn off output redirection */
  202.                     redirect=FALSE;
  203.                     break;
  204.  
  205.                 case 'v':        /* display informative messages */
  206.                     verbose=TRUE;
  207.                     break;
  208.  
  209.                 case 'n':        /* do not login on connect */
  210.                     autologin=FALSE;
  211.                     break;
  212.  
  213.                 case 'i':        /* interactive prompting off */
  214.                     prompt=FALSE;
  215.                     break;
  216.  
  217.                 case 'g':        /* wildcard expansion off */
  218.                     glob=FALSE;
  219.                     break;
  220.  
  221.                 case 'd':        /* debug, optional level */
  222.                     if(sscanf(argv[++i],"%d",&debug)<=0)
  223.                         debug=TRUE;
  224.                     break;
  225.  
  226.                 case 's':        /* do not change \ to / */
  227.                     slashflip=FALSE;
  228.                     break;
  229.  
  230.                 case 'h':        /* host file name */
  231.                     strcpy(Configfile,argv[++i]);
  232.                     break;
  233.  
  234.                 case 'm':        /* use built in |more */
  235.                     printf("\nusing more...");
  236.                     usemore=TRUE;
  237.                     lineslft=numlines=tel_vid_info.rows;
  238.                     printf("\nusing more...");
  239.                     break;
  240.  
  241.                 case 'e':        /* noninteractive commands with interactive login */
  242.                     f_enter_login=TRUE;
  243.  
  244.                 case 'p':        /* noninteractive with interactive password */
  245.                     ttypass=TRUE;
  246.  
  247.                 case 'f':                        /* noninteractive, optional filename */
  248.                     fromtty=FALSE;    /* noninteractive input */
  249.                     strcpy(fromfile,argv[++i]);
  250.                     if(fromfile[0]) {
  251.                            fromfp=fopen(fromfile,"r");
  252.                            if(fromfp==NULL) {
  253.                             sprintf(printline,"Could not open file: %s",fromfile);
  254.                             nputs(printline);
  255.                             return(1);
  256.                           } /* end if */
  257.                       } /* end if */
  258.                     break;
  259.  
  260.                 case '?':
  261.                     give_args();
  262.  
  263.                 default:                        /* unknown option */
  264.                     sprintf(printline,"Unrecognized option -%c ignored",argv[i][1]);
  265.                     nputs(printline);
  266.                     break;
  267.               } /* end switch */
  268.           } /* end if */
  269.         else
  270.             sscanf(argv[i],"%s",destname);     /* destination host */
  271.       } /* end for */
  272.  
  273. #ifdef OLD_WAY
  274.     *strrchr(argv[0],'\\')==0;    /* put null at end of pathname string */
  275.     Shostpath(argv[0]);                /* and set the path */
  276. #endif
  277.     Shostfile(Configfile);        /* open host file */
  278.  
  279. /*
  280. *  initialize network
  281. */
  282.     if(c=Snetinit()) {      /* cannot initialize network */
  283.         printerr();         /* display TCP/IP message */
  284.         nputs("Error initializing network");
  285.         if(c==-3)    /* check for BOOTP server not responding */
  286.             netshut();    /* release network */
  287.         return(1);
  288.       } /* end if */
  289.  
  290.     install_break((int *)&foundbreak);      /* install our BREAK handler */
  291.  
  292.     Sgetconfig(&def);               /* get information provided in hosts file */
  293.     if(destname[0]) 
  294.         sprintf(ftpcommand,"open %s",destname);    /* if destination specified, connect to it */
  295.     nputs("");                                    /* initializes screen if not done */
  296.  
  297.     do {
  298.         if(*ftpcommand) {
  299.             ftppi(ftpcommand);            /* if command available, execute it */
  300. if(debug>4)
  301.     nputs("after returning from ftppi() ");
  302.           } /* end if */
  303. /*        if(fromtty)
  304.           n_cur(n_row(),0);                 in case screen messed up */
  305.         putstring("ftp> ");                /* prompt */
  306.         lineslft=numlines;              /* for |more */
  307.         c=ftpgets(ftpcommand,200,1);    /* read cmd from user */
  308.       } while(c!=ABORT);                /* Alt-F3 aborts */
  309.     netclose(ftpnum);                    /* close command connection */
  310.     netshut();                            /* terminate network stuff */
  311.     remove_break();                     /* restore previous break handler */
  312.  
  313.     return(0);
  314. }   /* end main() */
  315.  
  316. void give_args(void) {
  317.     nputs("FTP [-dfghimnprsv?]  [hostname]");
  318.     nputs("     d-Debug [level]");
  319.     nputs("     f-input File <filename>");
  320.     nputs("     g-Global wildcard expansion off");
  321.     nputs("     h-Host file <filename>");
  322.     nputs("     i-Interactive prompting off");
  323.     nputs("     m-use built in More");
  324.     nputs("     n-No login on connect");
  325.     nputs("     p-input file with interactive Password <filename>");
  326.     nputs("     r-turn off command line output Redirection");
  327.     nputs("     s-turn off Slash flip (/\\)");
  328.     nputs("     v-Verbose");
  329.     nputs("     ?-This list");
  330.     exit(1);
  331. }   /* end give_args() */
  332.  
  333. /**********************************************************************
  334. * ftpgets-read a line from the keyboard
  335. *       returns ABORT if aborted, non-zero on success
  336. * char *s;            where to put the line
  337. * int lim,echo;       max chars to read, echo?
  338. ************************************************************************/
  339. static int ftpgets(char *s,int lim,int echo)
  340. {
  341.     int c,count,i;
  342.     char *save, *ret;
  343.  
  344.     count=0;        /* none read */
  345.     save=s;            /* beginning of line */
  346.  
  347.     if(foundbreak) {
  348.         foundbreak=0;
  349.         *s='\0';
  350.         nputs("");
  351.         return(ABORT);
  352.       } /* end if */
  353.     if(!fromtty) {
  354.         if(fromfp==NULL)
  355.             ret=fgets(s,lim,stdin);
  356.         else
  357.             ret=fgets(s,lim,fromfp);
  358.         if(ret==NULL) {
  359.             nputs("EOF or error on read from file\n");
  360.             if(connected) {
  361.                 ftpdo("QUIT","");
  362.                 connected=FALSE;
  363.               } /* end if */
  364.             netclose(ftpnum);                   /* close command connection */
  365.             netshut();
  366.             remove_break();
  367.             if(display_init) {                 /* Restore DOS' color scheme */
  368.                 n_color(dos_color);
  369.                 n_clear();          /* clear screen */
  370.                 n_wrap(1);          /* cursor positioning */
  371.                 n_cur(0,0);
  372.               } /* end if */
  373.             exit(1);
  374.           } /* end if */
  375.         s[strlen(s)-1]='\0';     /* remove newline */
  376.         if(echo && fromfp)
  377.             nputs(s);
  378.         return(strlen(s));
  379.       } /* end if */
  380.     while(1) {
  381.         if(foundbreak) {        /* abort */
  382.             s=save;             /* reset line */
  383.             *s='\0';            /* null line */
  384.             nputs("");            /* newline */
  385.             foundbreak=0;        /* break processed */
  386.             return(ABORT);    
  387.           }
  388.         /* SAR 9/13/90 */
  389.         if(!kbhit()) {         /* if no char available */
  390.             checkevent();        /* check event queue */
  391.             c=0;
  392.           } /* end if */
  393.         else
  394.             c=getch();         /* else get character */
  395.         switch(c) {                /* allow certain editing chars */
  396.             case BACKSPACE:
  397.             case 8:                /* backspace */
  398.                 if(count) {
  399.                     if(echo) {
  400.                         nputchar((char)8);
  401.                         nputchar(' ');
  402.                         nputchar((char)8);
  403.                       } /* end if */
  404.                     count--;    /* one less character */
  405.                     s--;        /* move pointer backward */
  406.                   } /* end if */
  407.                 break;
  408.  
  409.             case EOF:
  410.             case 13:            /* carriage return,=ok */
  411.                 nputs("");        /* newline */
  412.                 *s='\0';        /* terminate the string */
  413.                 return(c);        /* return ok */
  414.  
  415.             case 10:            /* line feed */
  416.                 break;            /* ignore */
  417.  
  418.             case 21:            /* kill line */
  419.                 for(i=0; i<s-save; i++) {    /* length of line */
  420.                     if(echo) {                /* erase */
  421.                         nputchar(8);
  422.                         nputchar(' ');
  423.                         nputchar(8);
  424.                       } /* end if */
  425.                   } /* end for */
  426.                 s=save;    /* reset line */
  427.                 break;
  428.  
  429.             case 0:                /* do nothing */
  430.                 break;
  431.  
  432.             default:                        /* not special char */
  433.                 if(c>31&&c<127) {            /* printable */
  434.                     if(echo) nputchar((char)c);    /* display */
  435.                     *s++=(char)c;                /* add to string */
  436.                     count++;    /* length of string */
  437.                   } /* end if */
  438.                 else            /* acts as eol */
  439.                     return(c);    /* value of special char */
  440.                 if(count==lim) {            /* to length limit */
  441.                     *s='\0';    /* terminate */
  442.                     return(c);    
  443.                   } /* end if */
  444.             break;
  445.           } /* end switch */
  446.       } /* end while */
  447. }   /* end ftpgets() */
  448.  
  449. /************************************************************************
  450. * dumpcon
  451. *  take everything from a connection and send it to the screen
  452. *  return -1 on closed connection, else 0, 1 if paused
  453. ************************************************************************/
  454.  
  455. static int dumpcon(int cnum)
  456. {
  457.     int cnt;
  458.  
  459.     if(fromtty && n_scrlck())
  460.         return(TRUE);                /* if paused, nothing to do */
  461.     do {
  462.         cnt=netread(cnum,s,64);        /* get some from queue */
  463.         telnet(cnt);                /* display on screen, etc.*/
  464.       } while(cnt>0);
  465.     return(cnt);                    /* 0 normally, -1 if connection closed */
  466. }   /* end dumpcon() */
  467.  
  468. /***********************************************************************
  469. *  telnet
  470. *   filter telnet options on incoming data
  471. ************************************************************************/
  472. static void telnet(int cnt)
  473. {
  474.     int i;
  475.  
  476. if(debug>4) {
  477.     sprintf(printline,"telnet(): cnt=%d ",cnt);
  478.     nputs(printline);
  479.   }    /* end if */
  480.     for(i=0; i<cnt; i++) {                    /* put on screen */
  481.         if(s[i] & 128) {                    /* if over ASCII 128 */
  482.             sprintf(printline," %d ",(int)s[i]);    /* show as number */
  483.             nputs(printline);
  484.           } /* end if */
  485.         else
  486.             nputchar(s[i]);
  487.       } /* end for */
  488. if(debug>4) {
  489.     nputs("telnet(): leaving ");
  490.   }    /* end if */
  491. }   /* end telnet() */
  492.  
  493. /********************************************************************
  494. * ftppi()
  495. *  Protocol interpreter for user interface commands
  496. *  Will permit any command to be abbreviated uniquely.
  497. *  Recognizes commands, translates them to the protocol commands to be
  498. *  sent to the other server, and uses userftpd, the daemon, to do data
  499. *  transfers.
  500. ***********************************************************************/
  501. static int ftppi(char *command)
  502. {
  503.     int retry;
  504.     int cmdno,i,j;
  505.     char cmdname[50],
  506.         word[50],
  507.         line[100],
  508.         answer[20],
  509.         ofilename[50];
  510.     char *p;
  511.     struct machinfo *mp;
  512.  
  513. if(debug>1) {           /* print command */
  514.     sprintf(printline,"command: %s",command);
  515.     nputs(printline);
  516.   } /* end if */
  517.  
  518.     if(!getword(command,cmdname))   /* removes first word from command */
  519.         return(FALSE);
  520.  
  521.     strlwr(cmdname);
  522.     cmdno=finduniq(cmdname,ftp_cmdlist,NCMDS);    /* search cmdlist for prefix */
  523.     if(cmdno==AMBIGUOUS) {        /* not unique abbreviation */
  524.         nputs("?Ambiguous command");
  525.         return(FALSE);
  526.       } /* end if */
  527.     if(cmdno==NONE) {        /* not a prefix of any command */
  528.         nputs("?Invalid command");
  529.         return(FALSE);
  530.       } /* end if */
  531.  
  532. /* change \ to / and check if command output redirected */
  533.     if(cmdno!=BANG) {        /* don't alter shell escape */
  534.         if(redirect) {        /* check for ouput redirection selected */
  535.             if(cmdno!=LLS)        /* do not flip slashes for LLS */
  536.                 checkoredir(command,ofilename,slashflip);    /* check redirection, flip \ */
  537.             else
  538.                 checkoredir(command,ofilename,FALSE);    /* check redirection */
  539.           }    /* end if */
  540.         else {                /* no output redirection */
  541.             if(cmdno!=LLS && slashflip)        /* don't flip slashes for LLS and check for slashflipping here and assume it in routine */
  542.                 flip_slashes(command,ofilename);
  543.           }    /* end else */
  544.       } /* end if */
  545.  
  546.     switch(cmdno) {     /* process commands */
  547.         case QMARK:
  548.         case HELP:
  549.             if(!command[0]) {                        /* no argument */
  550.                 nputs("Commands may be abbreviated. Commands are:\n");
  551. /* display command list */
  552.                 printline[0]='\0';
  553.                 for(i=0; i<NCMDS; i++) {
  554.                     sprintf(word,"%-16s",ftp_cmdlist[i]);    /* get word from list */
  555.                     strcat(printline,word);            /* add to line */
  556.                     if(i%5==4) {                    /* display line */
  557.                         printline[79]='\0';
  558.                         nputs(printline);
  559.                         printline[0]='\0';
  560.                       } /* end if */
  561.                   } /* end for */
  562.                 if(i%5!=4)
  563.                     nputs(printline);                /* last line */
  564.                 return(TRUE);
  565.               } /* end if */
  566. /* help for specific commands */
  567.             else {
  568.                 while(getword(command,word)) {        /* loop for all args */
  569.                     i=finduniq(word,ftp_cmdlist,NCMDS);       /* which command? */
  570.                     if(i==AMBIGUOUS)                        /* non-unique command name */
  571.                         sprintf(printline,"?Ambiguous help command %s",word);
  572.                     else 
  573.                         if(i==NONE)                    /* no such command */
  574.                             sprintf(printline,"?Invalid help command %s",word);
  575.                         else                            /* display help string */
  576.                             sprintf(printline,"%s",helpstrings[i-1]);
  577.                     nputs(printline);
  578.                   } /* end while */
  579.                 return(TRUE);
  580.               } /* end else */
  581.             break;
  582.  
  583.         case BANG:                            /* shell escape */
  584.             fflush(stdout);
  585.             if(*(stpblk(command))) {        /* command specified */
  586.                 system(command);            /* execute command */
  587.                 return(TRUE);
  588.               } /* end if */
  589.             dosescape();                    /* subshell */
  590.             return(TRUE);
  591.  
  592.         case BELL:
  593.             if(getword(command,word)) {        /* scan arg */
  594.                 strlwr(word);
  595.                 if(!strcmp(word,"off"))
  596.                      bell=FALSE;
  597.                 else 
  598.                     if(!strcmp(word,"on"))
  599.                         bell=TRUE;
  600.                 else 
  601.                     bell=!bell;
  602.               } /* end if */
  603.             else
  604.                  bell=!bell;
  605.             if(bell) 
  606.                 nputs("Bell mode on.");
  607.             else 
  608.                 nputs("Bell mode off.");
  609.             return(TRUE);
  610.  
  611.         case BYE:
  612.         case QUIT:
  613.             if(connected) {
  614.                 ftpdo("QUIT",ofilename);
  615.                 connected=FALSE;
  616.               } /* end if */
  617.             netclose(ftpnum);                    /* close command connection */
  618.             netshut();
  619.             remove_break();
  620.             if(display_init) {                 /* Restore DOS' color scheme */
  621.                 n_color(dos_color);
  622.                 n_clear();          /* clear screen */
  623.                 n_wrap(1);          /* cursor positioning */
  624.                 n_cur(0,0);
  625.               } /* end if */
  626.             exit(0);
  627.  
  628.         case DEBUG:                /* turn on/off debugging, optional level */
  629.             if(sscanf(command,"%d",&i)>0)
  630.                 debug=i;                            /* level */
  631.             else
  632.                 if(getword(command,word)) {            /* scan arg */
  633.                     strlwr(word);
  634.                     if(!strcmp(word,"off"))
  635.                         debug=FALSE;
  636.                     else 
  637.                         if(!strcmp(word,"on"))
  638.                             debug=TRUE;
  639.                         else
  640.                             debug=!debug;
  641.                   } /* end if */
  642.             else
  643.                 debug=!debug;
  644.             if(debug) {
  645.                 sprintf(printline,"Debugging on(debug=%d).",debug);
  646.                 nputs(printline);
  647.               } /* end if */
  648.             else 
  649.                 nputs("Debugging off.");
  650.             return(TRUE);
  651.  
  652.         case GLOB:        /* wildcard expansion */
  653.             if(getword(command,word)) {
  654.                 strlwr(word);
  655.                 if(!strcmp(word,"off")) 
  656.                     glob=FALSE;
  657.                 else 
  658.                     if(!strcmp(word,"on")) 
  659.                         glob=TRUE;
  660.                     else 
  661.                         glob=!glob;
  662.               } /* end if */
  663.             else 
  664.                 glob=!glob;
  665.             if(glob) 
  666.                 nputs("Globbing on.");
  667.             else 
  668.                 nputs("Globbing off.");
  669.             return(TRUE);
  670.  
  671.         case HASH:        /* hash mark printing */
  672.             if(getword(command,word)) {
  673.                 strlwr(word);
  674.                 if(!strcmp(word,"off")) 
  675.                     hash=FALSE;
  676.                 else 
  677.                     if(!strcmp(word,"on")) 
  678.                         hash=TRUE;
  679.                     else 
  680.                         hash=!hash;
  681.               } /* end if */
  682.             else 
  683.                 hash=!hash;
  684.             if(hash) 
  685.                 nputs("Hash mark printing on(1024 bytes/hash mark).");
  686.             else 
  687.                 nputs("Hash printing off.");
  688.             return(TRUE);
  689.  
  690.         case INTERACTIVE:    /* prompting on multiple transfers */
  691.             prompt=TRUE;
  692.             nputs("Interactive mode on.");
  693.             return(TRUE);
  694.  
  695.         case LCD:        /* change local directory */
  696.             if(command[1]==':') {        /* if disk specified */
  697. #ifdef    MSC
  698. #ifdef __TURBOC__
  699.                 setdisk(tolower(command[0])-'a');
  700. #else
  701.                 unsigned int bogus;
  702.                 _dos_setdrive( tolower( command[0])-'a'+1,&bogus);
  703. #endif
  704. #else
  705.                 chgdsk(tolower(command[0])-'a');
  706. #endif
  707.                 strcpy(command,&command[2]);
  708.               } /* end if */
  709.             if(*(stpblk(command))&&chdir(command))     /* CD */
  710.                 nputs("Unable to change directory");
  711.             getdir(0,line);        /* current directory */
  712.             sprintf(printline,"Local directory now %s",line);
  713.             nputs(printline);
  714.             return(TRUE);
  715.  
  716.         case LLS:        /* local DIR */
  717.             sprintf(line,"DIR %s",command);
  718.             fflush(stdout);
  719.             system(line);
  720.             return(TRUE);
  721.  
  722.         case MORE:        /* toggle use of MORE */
  723.             if(getword(command,word)) {
  724.                 strlwr(word);
  725.                 if(!strcmp(word,"off"))
  726.                     usemore=FALSE;
  727.                 else if(!strcmp(word,"on"))
  728.                     usemore=TRUE;
  729.               } /* end if */
  730.             else
  731.                 usemore=!usemore;
  732.             if(usemore)
  733.                 nputs("Use of built in | more on.");
  734.             else
  735.                 nputs("Use of built in | more off.");
  736.             lineslft=numlines=tel_vid_info.rows;
  737.             break;
  738.  
  739.         case NONINTERACTIVE:    /* turn off interactive prompting */
  740.             prompt=FALSE;
  741.             nputs("Interactive mode off.");
  742.             return(TRUE);
  743.  
  744.         case OPEN:        /* open connection to host */
  745.             if(connected) {
  746.                 nputs("Already connected.");
  747.                 return(FALSE);
  748.               } /* end if */
  749.             while(!(*(stpblk(command)))) {        /* no argument */
  750.                 putstring("To: ");
  751.                 if(ftpgets(command,100,1)==ABORT) 
  752.                     return(FALSE);
  753.               } /* end while */
  754.             getword(command,destname);  /* host name */
  755.             mp=Sgethost(destname);        /* get host info */
  756.             if(foundbreak)
  757.                 return(FALSE);          /* abort */
  758.             if(mp==NULL) {                /* try domain serving */
  759.                 Sdomain(destname);
  760.                 while(mp==NULL) {
  761.                     switch(checkevent()) {
  762.                         case ABORT:
  763.                             return(FALSE);    /* abort */
  764.  
  765.                         case DOMFAIL:
  766.                             printerr();
  767.                             sprintf(printline,"Unknown host: %s\n",destname);
  768.                             nputs(printline);
  769.                             return(FALSE);
  770.  
  771.                         case DOMOK:
  772.                             mp=Slooknum(ftpnum);    /* get host info */
  773.                             break;
  774.  
  775.                         default:
  776.                             break;
  777.                       } /* end switch */
  778.                   } /* end while */
  779.               } /* end if */
  780.             display_init=TRUE;
  781.             def.color[0]=(unsigned char)(mp->nfcolor+(mp->nbcolor<<4));
  782.             scrsetup=FALSE;
  783.             nputs("");
  784.             if(sscanf(command,"%d",&i)>0)    /* port number specified */
  785.                 ftpnum=Snetopen(mp,i);
  786.             else
  787.                 ftpnum=Snetopen(mp,HFTP);        /* default port */
  788.             if(foundbreak)
  789.                 return(FALSE);       /* abort */
  790.             if(ftpnum<0) {                /* error on open */
  791.                 printerr();
  792.                 sprintf(printline,"Unable to connect to %s",destname);
  793.                 nputs(printline);
  794.                 return(FALSE);
  795.               } /* end if */
  796.             j=ftpreplies(ftpnum,&i);      /* response from other end */
  797.             if(j==FALSE || j==ERROR || j==NONE || j==ABORT) {
  798.                 return(FALSE);
  799.               } /* end if */
  800.             if(foundbreak)
  801.                 return(FALSE);
  802.             connected=TRUE;
  803.             if(autologin) {        /* execute login command */
  804.                 strcpy(command,"user");
  805.                 ftppi(command);
  806.               } /* end if */
  807.             return(TRUE);
  808.  
  809.         case PROMPT:            /* interactive prompting */
  810.             if(getword(command,word)) {
  811.                 strlwr(word);
  812.                 if(!strcmp(word,"off")) 
  813.                     prompt=FALSE;
  814.                 else 
  815.                     if(!strcmp(word,"on")) 
  816.                         prompt=TRUE;
  817.                     else
  818.                         prompt=!prompt;
  819.               } /* end if */
  820.             else 
  821.                 prompt=!prompt;
  822.             if(prompt) 
  823.                 nputs("Interactive mode on.");
  824.             else 
  825.                 nputs("Interactive mode off.");
  826.             return(TRUE);
  827.  
  828.         case SENDPORT:            /* send PORT commands for each transfer */
  829.             if(getword(command,word)) {
  830.                 strlwr(word);
  831.                 if(!strcmp(word,"off")) 
  832.                     sendport=FALSE;
  833.                 else 
  834.                     if(!strcmp(word,"on")) 
  835.                         sendport=TRUE;
  836.                     else 
  837.                         sendport=!sendport;
  838.               } /* end if */
  839.             else 
  840.                 sendport=!sendport;
  841.             if(sendport) 
  842.                 nputs("Use of PORT cmds on.");
  843.             else 
  844.                 nputs("Use of PORT cmds off.");
  845.             return(TRUE);
  846.  
  847.         case SLASHFLIP:            /* change \ to / */
  848.             if(getword(command,word)) {
  849.                 strlwr(word);
  850.                 if(!strcmp(word,"off")) 
  851.                     slashflip=FALSE;
  852.                 else 
  853.                     if(!strcmp(word,"on")) 
  854.                         slashflip=TRUE;
  855.                     else 
  856.                         slashflip=!slashflip;
  857.               } /* end if */
  858.             else 
  859.                 slashflip=!slashflip;
  860.             if(slashflip) 
  861.                 nputs("Slash translation on.");
  862.             else 
  863.                 nputs("Slash translation off.");
  864.             return(TRUE);
  865.  
  866.         case STATUS:        /* display status info */
  867.             if(connected) {
  868.                 sprintf(printline,"Connected to %s",destname);
  869.                 nputs(printline);
  870.               } /* end if */
  871.             if(ftpfilemode==FASCII) 
  872.                 nputs("Transfer mode is ascii.");
  873.             else 
  874.                 nputs("Transfer mode is binary.");
  875.             if(bell) 
  876.                 nputs("Bell on."); else nputs("Bell off.");
  877.             if(debug) {
  878.                 sprintf(printline,"Debugging on.(Debug=%d)",debug);
  879.                 nputs(printline);
  880.               } /* end if */
  881.             else 
  882.                 nputs("Debugging off.");
  883.             if(glob) 
  884.                 nputs("Filename globbing on."); 
  885.             else 
  886.                 nputs("Filename globbing off.");
  887.             if(hash) 
  888.                 nputs("Hash-mark printing on.");
  889.             else 
  890.                 nputs("Hash-mark printing off.");
  891.             if(prompt)
  892.                 nputs("Interactive prompting on."); 
  893.             else 
  894.                 nputs("Interactive prompting off.");
  895.             if(sendport) 
  896.                 nputs("Sending of port commands on.");
  897.             else 
  898.                 nputs("Sending of PORT cmds off.");
  899.             if(slashflip) 
  900.                 nputs("Flipping \\ to / on.");
  901.             else
  902.                 nputs("Flipping \\ to / off.");
  903.             if(verbose) 
  904.                 nputs("Verbose mode on."); 
  905.             else 
  906.                 nputs("Verbose mode off.");
  907.             if(usemore)
  908.                 nputs("Use of built in | more on.");
  909.             else
  910.                 nputs("Use of built in | more off.");
  911.             if(connected) {        /* send STAT command */
  912.                 nputs("\nRemote status:");
  913.                 ftpdo("STAT",ofilename);
  914.               } /* end if */
  915.             return(TRUE);
  916.  
  917.         case VERBOSE:        /* display informative messages */
  918.             if(getword(command,word)) {
  919.                 strlwr(word);
  920.                 if(!strcmp(word,"off")) 
  921.                     verbose=FALSE;
  922.                 else 
  923.                     if(!strcmp(word,"on")) 
  924.                         verbose=TRUE;
  925.                     else 
  926.                         verbose=!verbose;
  927.               } /* end if */
  928.             else 
  929.                 verbose=!verbose;
  930.             if(verbose) 
  931.                 nputs("Verbose mode on.");
  932.             else 
  933.                 nputs("Verbose mode off.");
  934.             return(TRUE);
  935.  
  936.         default:        /* The other commands valid only if connected */
  937.             if(!connected) {
  938.                 nputs("Not connected.");
  939.                 return(FALSE);
  940.               } /* end if */
  941.  
  942.             switch(cmdno) {
  943.                 case ASCII:         /* transfer mode */
  944.                     ftpdo("TYPE A",ofilename);
  945.                     return(TRUE);
  946.  
  947.                 case BGET:          /* get file in binary mode */
  948.                     i=ftpfilemode;  /* save current mode */
  949.                     if(i==FASCII)
  950.                         ftpdo("TYPE I",ofilename);
  951.                     while(!(*(stpblk(command)))) {
  952.                         putstring("File: ");
  953.                         if(ftpgets(command,100,1)==ABORT)
  954.                             return(FALSE);
  955.                       } /* end while */
  956.                     sprintf(line,"RETR %s",command);
  957.                     ftpdo(line,ofilename);      /* get file */
  958.                     if(i==FASCII)
  959.                         ftpdo("TYPE A",ofilename);  /* restore mode */
  960.                     return(TRUE);
  961.  
  962.                 case BINARY:        /* binary mode */
  963.                     ftpdo("TYPE I",ofilename);
  964.                     return(TRUE);
  965.  
  966.                 case BPUT:          /* put file in binary mode */
  967.                     i=ftpfilemode;
  968.                     if(i==FASCII)
  969.                         ftpdo("TYPE I",ofilename);
  970.                     while(!(*(stpblk(command)))) {      /* if no arg */
  971.                         putstring("File: ");    /* get from user */
  972.                         if(ftpgets(command,100,1)==ABORT)
  973.                             return(FALSE);
  974.                       } /* end while */
  975.                     sprintf(line,"STOR %s",command);
  976.                     for(retry=0; retry<5; retry++) {
  977.                         if((i=ftpdo(line,ofilename))==TRUE) {
  978.                             if(i==FASCII)
  979.                                 ftpdo("TYPE A",ofilename);
  980.                             return(TRUE);
  981.                           } /* end if */
  982.                         else
  983.                             if(i!=FALSE) {
  984.                                 if(i==FASCII)
  985.                                     ftpdo("TYPE A",ofilename);
  986.                                 return(ERROR);
  987.                               } /* end if */
  988.                         printf("\nRetrying...");
  989.                       } /* end for */
  990.                     printf("Maximum retry count reached.  Aborting this file transfer...");
  991.                     return(FALSE);
  992.  
  993.                 case CD:        /* change remote directory */
  994.                     while(!(*(stpblk(command)))) {      /* if no arg, get from user */
  995.                         putstring("To: ");
  996.                         if(ftpgets(command,100,1)==ABORT)
  997.                             return(FALSE);  /* abort */
  998.                       } /* end while */
  999.                     getword(command,word);
  1000.                     if(!strcmp(word,"..")) {    /* special case */
  1001.                         i=ftpdo("CDUP",ofilename);
  1002.                         if(i!=ERROR)
  1003.                             return(TRUE);       /* if CDUP understood */
  1004.                         nputs("Trying again...");
  1005.                         i=ftpdo("XCUP",ofilename);  /* try alternative */
  1006.                         if(i!=ERROR)
  1007.                             return(TRUE);
  1008.                         nputs("Trying again...");       /* else try usual CD */
  1009.                       } /* end if */
  1010.                     sprintf(line,"CWD %s",word);        /* try CWD */
  1011.                     i=ftpdo(line,ofilename);
  1012.                     if(i!=ERROR)
  1013.                         return(TRUE);
  1014.                     nputs("Trying again...");
  1015.                     sprintf(line,"XCWD %s",word);       /* try XCWD */
  1016.                     ftpdo(line,ofilename);
  1017.                     return(TRUE);
  1018.  
  1019.                 case CLOSE:             /* drop connection */
  1020.                     ftpdo("QUIT",ofilename);
  1021.                     connected=FALSE;
  1022.                     return(TRUE);
  1023.  
  1024.                 case DEL:
  1025.                 case RM:
  1026.                     getword(command,word);
  1027.                     while(!word[0]) {   /* get arg from user */
  1028.                         putstring("File: ");
  1029.                         if(ftpgets(word,100,1)==ABORT)
  1030.                             return(FALSE);  /* abort */
  1031.                       } /* end while */
  1032.                     if(prompt) {        /* check interactively */
  1033.                         sprintf(printline,"Delete %s? ",word);
  1034.                         putstring(printline);
  1035.                         ftpgets(answer,20,1);
  1036.                         if(tolower(*(stpblk(answer)))!='y')
  1037.                             return(TRUE);
  1038.                       } /* end if */
  1039.                     sprintf(line,"DELE %s",word);
  1040.                     ftpdo(line,ofilename);
  1041.                     return(TRUE);
  1042.  
  1043.                 case DIR:       /* get list of remote files */
  1044.                     i=ftpfilemode;  /* save mode */
  1045.                     if(i==FIMAGE)
  1046.                         ftpdo("TYPE A",ofilename);
  1047.                     if(getword(command,word)) { /* do DIR */
  1048.                         sprintf(line,"LIST %s",word);
  1049.                         ftpdo(line,ofilename);
  1050.                       } /* end if */
  1051.                     else
  1052.                         ftpdo("LIST",ofilename);
  1053.                     if(i==FIMAGE)
  1054.                         ftpdo("TYPE I",ofilename);
  1055.                     return(TRUE);
  1056.  
  1057.                 case GET:
  1058.                 case RECV:      /* get remote file */
  1059.                     while(!(*(stpblk(command)))) {      /* if no arg */
  1060.                         putstring("File: ");
  1061.                         if(ftpgets(command,100,1)==ABORT)
  1062.                             return(FALSE);  /* abort */
  1063.                       } /* end while */
  1064.                     sprintf(line,"RETR %s",command);
  1065.                     ftpdo(line,ofilename);
  1066.                     return(TRUE);
  1067.  
  1068.                 case LS:        /* get remote file list-short */
  1069.                     i=ftpfilemode;
  1070.                     if(i==FIMAGE)
  1071.                         ftpdo("TYPE A",ofilename);
  1072.                     if(getword(command,word)) {
  1073.                         sprintf(line,"NLST %s",word);
  1074.                         ftpdo(line,ofilename);
  1075.                       } /* end if */
  1076.                     else
  1077.                         ftpdo("NLST",ofilename);
  1078.                     if(i==FIMAGE)
  1079.                         ftpdo("TYPE I",ofilename);
  1080.                     return(TRUE);
  1081.  
  1082.                 case MDELETE:
  1083.                     while(!(*(stpblk(command)))) {      /* no arg */
  1084.                         putstring("Files: ");
  1085.                         if(ftpgets(command,100,1)==ABORT)
  1086.                             return(FALSE);  /* abort */
  1087.                       } /* end while */
  1088.                     while(getword(command,word)) {      /* for each arg */
  1089.                         if(glob) {      /* wildcard expansion */
  1090.                             sprintf(line,"NLST %s",word);
  1091.                             capture=TRUE;
  1092.                             ftpdo(line,ofilename);  /* put exapnsion in captlist */
  1093.                             capture=FALSE;
  1094.                           } /* end if */
  1095.                         else
  1096.                             strcpy(captlist,word);  /* captlist has name(s) now */
  1097.                         while(getnname(captlist,word)) {    /* for each name */
  1098.                             if(prompt) {    /* check */
  1099.                                 sprintf(printline,"mdelete %s? ",word);
  1100.                                 putstring(printline);
  1101.                                 if(ftpgets(answer,20,1)==ABORT) {   /* abort */
  1102.                                     command[0]='\0';    /* no more processing */
  1103.                                     break;          /* quit immediately */
  1104.                                   } /* end if */
  1105.                                 if(tolower(*(stpblk(answer)))!='y')
  1106.                                     continue;
  1107.                               } /* end if */
  1108.                             sprintf(line,"DELE %s",word);   /* delete */
  1109.                             ftpdo(line,ofilename);
  1110.                           } /* end while */
  1111.                       } /* end while */
  1112.                     return(TRUE);
  1113.  
  1114.                 case MDIR:      /* remote multiple DIR */
  1115.                     i=ftpfilemode;  /* save mode */
  1116.                     if(i==FIMAGE)
  1117.                         ftpdo("TYPE A",ofilename);
  1118.                     while(!(*(stpblk(command)))) {      /* no arg */
  1119.                         putstring("Directories: ");
  1120.                         if(ftpgets(command,100,1)==ABORT)
  1121.                             return(FALSE);    /* abort */
  1122.                       } /* end while */
  1123.                     while(getword(command,word)) {      /* for each arg */
  1124.                         if(glob) {      /* expand wildcards */
  1125.                             sprintf(line,"NLST %s",word);
  1126.                             capture=TRUE;
  1127.                             ftpdo(line,ofilename);
  1128.                             capture=FALSE;
  1129.                           } /* end if */
  1130.                         else
  1131.                             strcpy(captlist,word);
  1132.                         while(getnname(captlist,word)) {    /* for each name */
  1133.                             if(prompt) {    /* check */
  1134.                                 sprintf(printline,"mdir %s? ",word);
  1135.                                 putstring(printline);
  1136.                                 if(ftpgets(answer,20,1)==ABORT) {   /* abort */
  1137.                                     command[0]='\0';    /* no more processing */
  1138.                                     break;          /* quit immediately */
  1139.                                   } /* end if */
  1140.                                 if(tolower(*(stpblk(answer)))!='y')
  1141.                                     continue;
  1142.                               } /* end if */
  1143.                             sprintf(line,"LIST %s",word);   /* DIR */
  1144.                             ftpdo(line,ofilename);
  1145.                           } /* end while */
  1146.                       } /* end while */
  1147.                     if(i==FIMAGE)
  1148.                         ftpdo("TYPE I",ofilename);
  1149.                     return(TRUE);
  1150.  
  1151.                 case MGET:      /* get multiple files */
  1152. #ifdef OLD_WAY
  1153.                     getword(command,line);
  1154. #else
  1155.                     strcpy(line,command);
  1156. #endif
  1157.                     while(!line[0]) {   /* no arg */
  1158.                         putstring("Files: ");
  1159.                         if(ftpgets(line,100,1)==ABORT)
  1160.                             return(FALSE);  /* abort */
  1161.                       } /* end if */
  1162.                     while(getword(line,word)) { /* for each arg */
  1163.                         if(glob) {      /* expand wildcards */
  1164.                             sprintf(command,"NLST %s",word);
  1165.                             capture=TRUE;
  1166.                             ftpdo(command,ofilename);
  1167.                             capture=FALSE;
  1168.                           } /* end if */
  1169.                         else
  1170.                             strcpy(captlist,word);
  1171.                         while(getnname(captlist,word)) {    /* for each name */
  1172.                             if(prompt) {    /* check */
  1173.                                 sprintf(printline,"mget %s? (Yes/No/All/Quit) ",word);
  1174.                                 putstring(printline);
  1175.                                 if((ftpgets(answer,20,1)==ABORT) || (tolower(*(stpblk(answer)))=='q')) {  /* abort */
  1176.                                     command[0]='\0';    /* no more processing */
  1177.                                     break;          /* quit immediately */
  1178.                                   } /* end if */
  1179.                                 if(tolower(*(stpblk(answer)))=='a') {   /* All */
  1180.                                     prompt=FALSE;
  1181.                                     tempprompt=TRUE;
  1182.                                   } /* end if */
  1183.                                 if((tolower(*(stpblk(answer)))!='y') && (tolower(*(stpblk(answer)))!='a'))
  1184.                                     continue;
  1185.                               } /* end if */
  1186.                             sprintf(command,"RETR \"%s\"",word);
  1187.                             ftpdo(command,ofilename);
  1188.                           } /* end while */
  1189.                         if(tempprompt==TRUE) {
  1190.                             prompt=TRUE;
  1191.                             tempprompt=FALSE;
  1192.                           } /* end if */
  1193.                       } /* end while */
  1194.                     return(TRUE);
  1195.  
  1196.                 case MKDIR:     /* create directory */
  1197.                     while(!(*(stpblk(command)))) {      /* no arg */
  1198.                         putstring("Directory: ");
  1199.                         if(ftpgets(command,100,1)==ABORT)
  1200.                             return(FALSE);  /* abort */
  1201.                       } /* end while */
  1202.                     sprintf(line,"XMKD %s",command);    /* try XMKD */
  1203.                     i=ftpdo(line,ofilename);
  1204.                     if(i!=ERROR)
  1205.                         return(TRUE);
  1206.                     nputs("Trying again...");
  1207.                     sprintf(line,"MKD %s",command);     /* else try MKD */
  1208.                     ftpdo(line,ofilename);
  1209.                     return(TRUE);
  1210.  
  1211.                 case MLS:
  1212.                     i=ftpfilemode;
  1213.                     if(i==FIMAGE)
  1214.                         ftpdo("TYPE A",ofilename);
  1215.                     while(!(*(stpblk(command)))) {      /* no arg */
  1216.                         putstring("Directories: ");
  1217.                         if(ftpgets(command,100,1)==ABORT)
  1218.                             return(FALSE);  /* abort */
  1219.                       } /* end while */
  1220.                     while(getword(command,word)) {      /* for each arg */
  1221.                         if(glob) {      /* exapnd wildcards */
  1222.                             sprintf(line,"NLST %s",word);
  1223.                             capture=TRUE;
  1224.                             ftpdo(line,ofilename);
  1225.                             capture=FALSE;
  1226.                           } /* end if */
  1227.                         else
  1228.                             strcpy(captlist,word);
  1229.                         while(getnname(captlist,word)) {    /* for each name */
  1230.                             if(prompt) {        /* check */
  1231.                                 sprintf(printline,"mls %s? ",word);
  1232.                                 putstring(printline);
  1233.                                 if(ftpgets(answer,20,1)==ABORT) {  /* abort */
  1234.                                     command[0]='\0';    /* no more processing */
  1235.                                     break;          /* quit immediately */
  1236.                                   } /* end if */
  1237.                                 if(tolower(*(stpblk(answer)))!='y')
  1238.                                     continue;
  1239.                               } /* end if */
  1240.                             sprintf(line,"NLST %s",word);   /* DIR */
  1241.                             ftpdo(line,ofilename);
  1242.                           } /* end while */
  1243.                       } /* end while */
  1244.                     if(i==FIMAGE)
  1245.                         ftpdo("TYPE I",ofilename);
  1246.                     return(TRUE);
  1247.  
  1248.                 case MODE:      /* set stream mode */
  1249.                     getword(command,word);
  1250.                     strlwr(word);
  1251.                     if(strncmp(word,"stream",strlen(word)))
  1252.                         nputs("We only support stream mode, sorry.");
  1253.                     else
  1254.                         nputs("Mode is stream.");
  1255.                     return(TRUE);
  1256.  
  1257.                 case MPUT:      /* put multiple files */
  1258. #ifdef OLD_WAY
  1259.                     getword(command,line);
  1260. #else
  1261.                     strcpy(line,command);
  1262. #endif
  1263.                     while(!line[0]) {   /* no arg */
  1264.                         putstring("Files: ");
  1265.                         if(ftpgets(line,100,1)==ABORT)
  1266.                             return(FALSE);  /* abort */
  1267.                       } /* end while */
  1268.                     p=NULL; /* no names expanded yet */
  1269.                     while(getword(line,word)) { /* for each arg */
  1270.                         do {        /* for each name */
  1271.                             if(glob) {      /* local wildcard expansion */
  1272.                                 if(p==NULL) {   /* if no expansions yet */
  1273.                                     p=firstname(word,0);    /* get first name, with no file information attached */
  1274.                                     if(p==NULL) {   /* if no expansions */
  1275.                                         sprintf(printline,"No match for %s",word);
  1276.                                         nputs(printline);
  1277.                                         continue;
  1278.                                       } /* end if */
  1279.                                   } /* end if */
  1280.                                 else {      /* not first name */
  1281.                                     p=nextname(0);      /* get next name, with no file information attached */
  1282.                                     if(p==NULL)
  1283.                                         continue;   /* if no names, next arg */
  1284.                                   } /* end else */
  1285.                               } /* end if */
  1286.                             else
  1287.                                 p=word;     /* no expansion */
  1288.                             if(prompt) {    /* check */
  1289.                                 sprintf(printline,"mput %s? (Yes/No/All/Quit) ",p);
  1290.                                 putstring(printline);
  1291.                                 if((ftpgets(answer,20,1)==ABORT)||(tolower(*(stpblk(answer)))=='q')) {  /* abort */
  1292.                                     command[0]='\0';    /* no more processing */
  1293.                                     break;          /* quit immediately */
  1294.                                   } /* end if */
  1295.                                 if(tolower(*(stpblk(answer)))=='a') {
  1296.                                     prompt=FALSE;
  1297.                                     tempprompt=TRUE;
  1298.                                   } /* end if */
  1299.                                 if((tolower(*(stpblk(answer)))!='y')&&(tolower(*(stpblk(answer)))!='a'))
  1300.                                     continue;
  1301.                               } /* end if */
  1302.                             sprintf(command,"STOR \"%s\"",p);   /* name may have special chars */
  1303.                             ftpdo(command,ofilename);
  1304.                           } while(glob && p!=NULL);       /* Not last expansion */
  1305.                         if(tempprompt) {
  1306.                             prompt=TRUE;
  1307.                             tempprompt=FALSE;
  1308.                           } /* end if */
  1309.                       } /* end while */
  1310.                     return(TRUE);
  1311.  
  1312.                 case PUT:
  1313.                 case SEND:      /* put file */
  1314.                     while(!(*(stpblk(command)))) {      /* no args */
  1315.                         putstring("File: ");
  1316.                         if(ftpgets(command,100,1)==ABORT)
  1317.                             return(FALSE);
  1318.                       } /* end while */
  1319.                     sprintf(line,"STOR %s",command);    /* put file */
  1320.                     for(retry=0; retry<5; retry++) {
  1321.                         if((i=ftpdo(line,ofilename))==TRUE)
  1322.                             return(TRUE);
  1323.                         else if(i!=FALSE)
  1324.                             return(ERROR);
  1325.                         printf("\nRetrying...");
  1326.                       } /* end for */
  1327.                     printf("\nMaximum retry count reached.  Aborting file transfer...");
  1328.                     return(ERROR);
  1329.  
  1330.                 case PWD:
  1331.                     i=ftpdo("XPWD",ofilename);      /* try XPWD */
  1332.                     if(i!=ERROR)
  1333.                         return(TRUE);
  1334.                     nputs("Trying again...");
  1335.                     ftpdo("PWD",ofilename);         /* else try PWD */
  1336.                     return(TRUE);
  1337.  
  1338.                 case QUOTE:
  1339.                     while(!(*(stpblk(command)))) {      /* no arg */
  1340.                         putstring("Command: ");
  1341.                         if(ftpgets(command,100,1)==ABORT)
  1342.                             return(FALSE);
  1343.                       } /* end while */
  1344.                     ftpdo(command,ofilename);       /* send command */
  1345.                     return(TRUE);
  1346.  
  1347.                 case REMOTEHELP:                /* get help */
  1348.                     if(*(stpblk(command))) {        /* for specific command */
  1349.                         sprintf(line,"HELP %s",command);
  1350.                         ftpdo(line,ofilename);
  1351.                       } /* end if */
  1352.                     else
  1353.                         ftpdo("HELP",ofilename);        /* generic help */
  1354.                     return(TRUE);
  1355.  
  1356.                 case RENAME:        /* rename remote file */
  1357.                     while(!(*(stpblk(command)))) {      /* no arg */
  1358.                         putstring("From: ");
  1359.                         if(ftpgets(command,100,1)==ABORT)
  1360.                             return(FALSE);
  1361.                       } /* end if */
  1362.                     getword(command,word);
  1363.                     sprintf(line,"RNFR %s",word);
  1364.                     ftpdo(line,ofilename);      /* send rename from name */
  1365.                     while(!(*(stpblk(command)))) {      /* no second arg */
  1366.                         putstring("To: ");
  1367.                         if(ftpgets(command,100,1)==ABORT) {
  1368.                             ftpdo("ABOR",ofilename);
  1369.                             return(FALSE);
  1370.                           } /* end if */
  1371.                       } /* end while */
  1372.                     sprintf(line,"RNTO %s",command); /* send rename to name */
  1373.                     ftpdo(line,ofilename);
  1374.                     return(TRUE);
  1375.  
  1376.                 case RMDIR:         /* remove remote dir */
  1377.                     while(!(*(stpblk(command)))) {      /* no arg */
  1378.                         putstring("Directory: ");
  1379.                         if(ftpgets(command,100,1)==ABORT)
  1380.                             return(FALSE);
  1381.                       } /* end while */
  1382.                     sprintf(line,"XRMD %s",command);    /* try XRMD */
  1383.                     i=ftpdo(line,ofilename);
  1384.                     if(i!=ERROR)
  1385.                         return(TRUE);
  1386.                     nputs("Trying again...");
  1387.                     sprintf(line,"RMD %s",command);     /* try RMD */
  1388.                     ftpdo(line,ofilename);
  1389.                     return(TRUE);
  1390.  
  1391.                 case STRUCT:        /* set structure type-only file */
  1392.                     getword(command,word);
  1393.                     strlwr(word);
  1394.                     if(strncmp(word,"file",strlen(word)))
  1395.                         nputs("We only support file structure, sorry.");
  1396.                     else
  1397.                         nputs("Structure is file.");
  1398.                     return(TRUE);
  1399.  
  1400.                 case TYPE:      /* set transfer type */
  1401.                     if(!getword(command,word)) {    /* no arg, just show */
  1402.                         if(ftpfilemode==FASCII)
  1403.                             nputs("Transfer type is ascii.");
  1404.                         else
  1405.                             nputs("Transfer type is binary.");
  1406.                       } /* end if */
  1407.                     strlwr(word);
  1408.                     if(!strncmp(word,"ascii",strlen(word)))
  1409.                         ftpdo("TYPE A",ofilename);
  1410.                     else
  1411.                         if(!strncmp(word,"binary",strlen(word))||!strncmp(word,"image",strlen(word)))
  1412.                             ftpdo("TYPE I",ofilename);
  1413.                         else {
  1414.                             sprintf(printline,"Unrecognized type: %s",word);
  1415.                             nputs(printline);
  1416.                           } /* end else */
  1417.                     return(TRUE);
  1418.  
  1419.                 case USER:          /* login to remote machine */
  1420.                     if(!fromtty && ttypass)
  1421.                         fromtty=TRUE; /* go interactive */
  1422.                     if(f_enter_login) {
  1423.                         fromtty=1;        /* fake interactive mode */
  1424.                         n_cur(n_row(),0);   /* in case screen is messed up */
  1425.                       } /* end if */
  1426.                     if(!(*(stpblk(command)))) { /* null response to prompt ok */
  1427.                         putstring("Username: ");
  1428.                         if(ftpgets(command,100,1)==ABORT)
  1429.                             return(FALSE);
  1430.                       } /* end if */
  1431.                     sprintf(line,"USER %s",command);    /* username */
  1432.                     switch(ftpdo(line,ofilename)) {
  1433.                         case TRUE:
  1434.                             return (TRUE);
  1435.                         case FALSE:
  1436.                         case ERROR:
  1437.                             return(FALSE);
  1438.                         case ABORT:
  1439.                             return(ABORT);
  1440.                         default:
  1441.                             break;
  1442.                       } /* end switch */
  1443.                     putstring("Password: ");
  1444.                     if(ftpgets(word,40,0)==ABORT)
  1445.                         return(FALSE);      /* no echoing */
  1446.                     if(f_enter_login)      /* restore to non-interactive mode */
  1447.                         fromtty=0;
  1448.                     sprintf(line,"PASS %s",word);       /* password */
  1449.                     if(ftpdo(line,ofilename)==INCOMPLETE) { /* if account needed */
  1450.                         do {
  1451.                             putstring("Account: ");
  1452.                             if(ftpgets(command,100,1)==ABORT)
  1453.                                 return(FALSE);
  1454.                           } while(!(*(stpblk(command))));
  1455.                         sprintf(line,"ACCT %s",command);
  1456.                         ftpdo(line,ofilename);
  1457.                       } /* end if */
  1458.                     if(ttypass)
  1459.                         fromtty=FALSE;     /* back to batch */
  1460.                     return(TRUE);
  1461.  
  1462.                 case ACCOUNT:
  1463.                     if(!(*(stpblk(command)))) {   /* null response to prompt OK */
  1464.                         putstring("Account: ");
  1465.                         if(ftpgets(command,100,0)==ABORT)
  1466.                             return(FALSE); /* no echo */
  1467.                         while (!(*(stpblk(command))));
  1468.                         sprintf(line,"ACCT %s",command);
  1469.                         ftpdo(line,ofilename);
  1470.                       } /* end if */
  1471.                     return(TRUE);
  1472.  
  1473.                 case SITE:      /* site commands */
  1474.                     while(!(*(stpblk(command)))) {      /* if no arg */
  1475.                         putstring("Site: ");
  1476.                         if(ftpgets(command,100,1)==ABORT)
  1477.                             return(FALSE);  /* abort */
  1478.                       } /* end while */
  1479.                     sprintf(line,"SITE %s",command);
  1480.                     ftpdo(line,ofilename);
  1481.                     return(TRUE);
  1482.  
  1483.                 default:    /* unknown command */
  1484.                     sprintf(printline,"***Program error: Unknown command no: %d",cmdno);
  1485.                     nputs(printline);
  1486.                     break;
  1487.               } /* end switch */
  1488.       } /* end switch */
  1489. }   /* end ftppi() */
  1490.  
  1491. /************************************************************************
  1492. * ftpdo
  1493. *  Do whatever command is sent from the user interface using
  1494. *  userftpd, the background file handler
  1495. *  Returns code from ftpreplies
  1496. ************************************************************************/
  1497.  
  1498. static int ftpdo(char *s,char *ofile)
  1499. {
  1500.     int i,
  1501.         rcode;
  1502.     char name[50],
  1503.         name2[50];
  1504.  
  1505.     for(i=0; i<4; i++)
  1506.         s[i]=(char)toupper(s[i]);  /* command to upper case */
  1507.  
  1508.     if(!strncmp(s,"STOR",4)) {    /* put file */
  1509.         getword(&s[5],name);    /* first arg-local file */
  1510.         if(!s[5]) 
  1511.             strcpy(&s[5],name);        /* if only one argument */
  1512.         else {
  1513.             getword(&s[5],name2);   /* second arg-removes quotes etc. */
  1514.             strcpy(&s[5],name2);    /* copy back into command */
  1515.           } /* end else */
  1516. #ifdef MSC
  1517.         if(0>(ftpfh=open(name,O_RDONLY | O_BINARY))) {    /* open local file */
  1518. #else
  1519.         if(0 >(ftpfh=open(name,O_RAW))) {    /* open local file */
  1520. #endif    
  1521.             nputs(" Cannot open file to transfer.");
  1522.             return(-1);
  1523.           } /* end if */
  1524.         ftpdata=netlisten(ftpport());        /* open data connection */
  1525.         ftpstate=20;
  1526.       } /* end if */
  1527.     else if(!strncmp(s,"RETR",4)) {  /* get file */
  1528.         getword(&s[5],name);            /* remote file */
  1529.         if(s[5])        /* two args present */
  1530.             getword(&s[5],name2);   /* local file */
  1531.         else
  1532.             check_file_name (name, name2);
  1533. #ifdef  MSC
  1534.         ftpfh=open(name2,O_BINARY|O_CREAT+O_WRONLY,S_IREAD|S_IWRITE);
  1535. #else
  1536.         ftpfh=creat(name2,O_RAW);              /* open local file */
  1537. #endif
  1538.         if(ftpfh<0) {
  1539.             printf(printline,"Cannot open file to receive: %s\n",name);
  1540.             nputs(printline);
  1541.             return(-1);
  1542.           } /* end if */
  1543.         strcpy(&s[5],name); /* put remote name back into command */
  1544.         ftpdata=netlisten(ftpport());       /* open data connection */
  1545.         ftpstate=30;
  1546.       } /* end if */
  1547.     else if(!strncmp(s,"LIST",4) || !strncmp(s,"NLST",4)) {
  1548.         if(capture)
  1549.             captlist[0]='\0';   /* where to put incoming data */
  1550. if(debug>4) {
  1551.     nputs("ftpdo(): before calling ftpport() ");
  1552.   }    /* end if */
  1553.         ftpdata=netlisten(ftpport());       /* data connection */
  1554. if(debug>4) {
  1555.     nputs("ftpdo(): after calling ftpport() ");
  1556.   }    /* end if */
  1557.         ftpstate=40;
  1558.       } /* end if */
  1559.     else if(!strncmp(s,"TYPE",4)) {
  1560.         if(toupper(s[5])=='I')
  1561.             ftpfilemode=FIMAGE; /* remember mode */
  1562.         else
  1563.             if(toupper(s[5])=='A')
  1564.                 ftpfilemode=FASCII;
  1565.       } /* end if */
  1566.  
  1567.     dumpcon(ftpnum);            /* clear command connection */
  1568.     netpush(ftpnum);
  1569.     netwrite(ftpnum,s,strlen(s));        /* send command */
  1570.     netwrite(ftpnum,"\r\n",2);        /* <CRLF> terminates command */
  1571.     if(!capture && ofile[0]) {        /* command redirected */
  1572.         if((ftpstate!=20) &&(ftpstate!=30)) {    /* not get or put */
  1573. #ifdef    MSC
  1574.              if(0>(ftpfh=open(ofile,O_CREAT|O_APPEND|O_WRONLY,S_IWRITE|S_IREAD)))
  1575. #else
  1576.              if(0>(ftpfh=open(ofile,O_CREAT|O_APPEND|O_WRONLY,S_IWRITE)))
  1577. #endif
  1578.                 nputs(" Cannot open output file.");
  1579.             else
  1580.                 if(ftpdata>-1)
  1581.                     ftpstate=30;    /* act as get, since data goes into file */
  1582.                 else {
  1583.                     close(ftpfh);
  1584.                     ftpfh=0;
  1585.                   } /* end else */
  1586.           } /* end if */
  1587.       } /* end if */
  1588. if(debug) {
  1589.     sprintf(printline,"---> %s",s); /* show command sent */
  1590.     nputs(printline);
  1591.     if(debug>=7) {
  1592.         for(i=0; i<(int)strlen(s); i++)
  1593.             sprintf(&printline[4*i],"%3d ",s[i]);
  1594.         nputs(printline);
  1595.       }
  1596.   }
  1597.     i=ftpreplies(ftpnum,&rcode);        /* get remote response */
  1598. if(debug) {
  1599.     nputs("after ftpreplies() call, in ftpdo ");
  1600.   }    /* end if */
  1601.     if((i==NONE) && strncmp(s,"QUIT",4)) {    /* unexpected connection drop */
  1602.         nputs("lost connection");
  1603.         connected=FALSE;
  1604.       } /* end if */
  1605.     if(i==ABORT || i==NONE || i==ERROR || i==FALSE)  {
  1606.         ftpstate=0;        /* if error, no transfer */
  1607.         if(ftpdata>-1)
  1608.             netclose(ftpdata);
  1609.         if(ftpfh!=0)
  1610.             close(ftpfh);
  1611.         ftpdata=-1;
  1612.         ftpfh=0;
  1613.       } /* end if */
  1614.     return(i);
  1615. }   /* end ftpdo() */
  1616.  
  1617. /************************************************************************
  1618. *   ftpport
  1619. *   return a new port number so that we don't try to re-use ports
  1620. *   before the mandatory TCP timeout period. (lifetime of a packet)
  1621. *   use a time-based initial port selection scheme.
  1622. ************************************************************************/
  1623. static unsigned int ftpport(void)
  1624. {
  1625.     unsigned int i,
  1626.         rcode;
  1627.     unsigned char hostnum[5];
  1628.     char sendline[60];        /* for port command */
  1629.  
  1630.     if(!sendport)            /* default port */
  1631.         return(HFTP-1);
  1632.     if(curftpprt<0x4000) {     /* restart cycle */
  1633.         i=(unsigned int)time(NULL);
  1634.         curftpprt=(unsigned int)(0x4000+(i&0x3fff));
  1635.       } /* end if */
  1636.     i=curftpprt--;            /* get port, update for next time */
  1637.     netgetip(hostnum);        /* get my ip number */
  1638.     sprintf(sendline,"PORT %d,%d,%d,%d,%d,%d\r\n",hostnum[0],hostnum[1],hostnum[2],hostnum[3],i/256,i&255);    /* full port number */
  1639. if(debug>1)
  1640.     nputs(sendline);
  1641.     netpush(ftpnum);        /* empty command connection */
  1642.     netwrite(ftpnum,sendline,strlen(sendline));    /* send PORT command */
  1643. if(debug>1) {
  1644.     nputs("ftpport(): before dumpcon() call ");
  1645.   }    /* end if */
  1646. /* check result of command, make sure port was okay */
  1647. /* return 0 on error */        /* ????? */
  1648.     dumpcon(ftpnum);
  1649. if(debug>1) {
  1650.     nputs("ftpport(): before ftpreplies() call ");
  1651.   }    /* end if */
  1652.     ftpreplies(ftpnum,&rcode);    /* get response */
  1653. if(debug>1) {
  1654.     sprintf(printline,"ftpport(): after ftpreplies() call, i=%d ",i);
  1655.     nputs(printline);
  1656.   }    /* end if */
  1657.     return(i);        /* port number */
  1658. }   /* end ftpport() */
  1659.  
  1660. /************************************************************************
  1661. * ftpreplies
  1662. * get responses to commands to server
  1663. * return TRUE on successful completion, FALSE on transient negative
  1664. * completion, INCOMPLETE if more commands needed for operation,
  1665. * NONE on lost connection, ABORT on user abort and ERROR on failure
  1666. *
  1667. ************************************************************************/
  1668. static int ftpreplies(int cnum,int *rcode)
  1669. {
  1670.     int cnt,ev,j=0;
  1671.  
  1672.     while(1) {
  1673. if(debug>4) {
  1674.     nputs("ftpreplies(): before rgetline() call ");
  1675.   }    /* end if */
  1676.         cnt=rgetline(cnum);     /* get line from remote host */
  1677. if(debug>4) {
  1678.     sprintf(printline,"s=%s cnt=%d ",s,cnt);
  1679.     nputs(printline);
  1680.   }    /* end if */
  1681.         if(cnt==NONE)
  1682.             return(NONE);        /* lost connection */
  1683.         if(cnt==ABORT) {        /* user abort */
  1684.             netpush(cnum);
  1685.             netwrite(cnum,"ABOR\r\n",6);        /* send abort */
  1686.             return(ABORT);
  1687.           } /* end if */
  1688.         if(!sscanf(s,"%d",rcode))
  1689.             *rcode=-1;                    /* continuation line */
  1690.         if((*rcode/100)==2) {            /* positive completion */
  1691.             dumpcon(ftpnum);            /* clear command connection */
  1692.             while(ftpdata>=0) {            /* wait till transfers complete */
  1693.                 ev=checkevent();
  1694. if(debug>4) {
  1695.     sprintf(printline,"ev=%d ",ev);
  1696.     nputs(printline);
  1697.   }    /* end if */
  1698.                 if(ev==NONE)
  1699.                     return(NONE);        /* lost connection */
  1700.                 if(ev==ABORT)
  1701.                     return(ABORT);      /* user abort */
  1702.  
  1703.                 if(ev==HAVEDATA)
  1704.                     dumpcon(ftpnum);    /* msg on command connection */
  1705.               } /* end while */
  1706.           } /* end if */
  1707.         if(verbose || (*rcode==-1) || (*rcode>500))
  1708.             telnet(cnt);                /* informative/error msg or display on */
  1709.         if(j)
  1710.             if(*rcode==j)
  1711.                 j=0;                    /* end of continuation */
  1712.             else 
  1713.                 continue;
  1714.         else 
  1715.             if(s[3]=='-') {                /* line with continuations */
  1716.                 j=*rcode;                            /* remember end code */
  1717.                 continue;
  1718.               } /* end if */
  1719. if(debug>4) {
  1720.     sprintf(printline,"*rcode=%d ",*rcode);
  1721.     nputs(printline);
  1722.   }    /* end if */
  1723.         switch((int)(*rcode/100)) {        /* first digit */
  1724.             case 1:                        /* preliminary */
  1725.                 continue;
  1726.     
  1727.             case 2:                        /* positive completion */
  1728.                 return(TRUE);
  1729.                 break;
  1730.  
  1731.             case 3:                        /* intermediate */
  1732.                 return(INCOMPLETE);
  1733.                 break;
  1734.         
  1735.             case 4:                        /* transient negative completion */
  1736.                 return(FALSE);
  1737.                 break;
  1738.  
  1739.             case 5:                        /* Permanent negative completion */
  1740.                 return(ERROR);
  1741.                 break;
  1742.  
  1743.             default:
  1744.                 nputs("Server response not understood. Terminating command\n");
  1745.                 return(ERROR);
  1746.           }    /* end switch */
  1747.       }    /* end while */
  1748. }   /* end ftpreplies() */
  1749.  
  1750. /************************************************************************
  1751. * rgetline-get a line from remote server
  1752. * return ABORT on user ABORT, NONE on lost connection,
  1753. * length of received line on success
  1754. *
  1755. ************************************************************************/
  1756. static int rgetline(int cnum)
  1757. {
  1758.     int cnt,
  1759.         i=0,
  1760.         ev;
  1761.  
  1762.     while(1) {
  1763. if(debug>4)
  1764.     nputs("rgetline(): before checkevent() ");
  1765.         ev=checkevent();
  1766. if(debug>4) {
  1767.     printf("\nevent: %d\n",ev);
  1768.     nputs("rgetline(): after checkevent() ");
  1769. }   /* end if */
  1770.  
  1771.         switch(ev) {
  1772.             case ABORT:                /* user abort */
  1773.             case NONE:                /* lost connection */
  1774.                 return(ev);
  1775.  
  1776.             case HAVEDATA:
  1777.                 if(fromtty && n_scrlck())
  1778.                     cnt=0;                    /* if paused, nothing to do */
  1779.                 else 
  1780.                     while(1) {
  1781.                         cnt=netread(cnum,&s[i],1);    /* get some from queue */
  1782.                         if(!cnt) 
  1783.                             break;            /* nothing available */
  1784.                         if(s[i++]=='\n') {    /* end of line */
  1785.                             s[i]='\0';
  1786. if(debug>3) {
  1787.     sprintf(printline,"rgetline(): s=%s, i=%d ",s,i);
  1788.     nputs(printline);
  1789.   }    /* end if */
  1790.                             return(i);        /* return line length */
  1791.                           } /* end if */
  1792.                       } /* end while */
  1793.                 break;
  1794.  
  1795.             default:        /* ignore other events */
  1796.                 break;
  1797.           } /* end switch */
  1798.       } /* end while */
  1799. }   /* end rgetline() */
  1800.  
  1801. #ifdef OLD_WAY
  1802. /************************************************************************
  1803. * breakstop
  1804. * handle cntrl-break
  1805. ************************************************************************/
  1806. static void breakstop(void)
  1807. {
  1808. #ifdef MSC
  1809.     signal(SIGINT,SIG_IGN);        /* ignore interrupts while processing this routine */
  1810. #endif
  1811.     foundbreak=1;
  1812. #ifdef MSC
  1813.     signal(SIGINT,breakstop);    /* reset Microsoft interception of break */
  1814. #endif
  1815. }   /* end breakstop() */
  1816. #endif
  1817.  
  1818. /************************************************************************
  1819. * userftpd
  1820. *  FTP receive and send file functions
  1821. ************************************************************************/
  1822. static void userftpd(void )
  1823. {
  1824.     int i,
  1825.         r1,
  1826.         r2;
  1827.     char lastchar;
  1828.     double rate;
  1829.     static int stopcapture=FALSE;    /* bytes xferred % 1024 */
  1830.     static long tbytes;
  1831.  
  1832.     switch(ftpstate) {
  1833.         default:                    /* unknown */
  1834.             break;
  1835.  
  1836.         case 40:                /* start LIST */
  1837.             if(!netest(ftpdata)) {
  1838.                 start=time(NULL);    /* current time */
  1839.                 tbytes=0;        /* received so far */
  1840.                 ftpstate=41;
  1841.               } /* end if */
  1842.             break;
  1843.  
  1844.         case 41:        /* get started */
  1845.             do {
  1846.                 if(capture && !stopcapture) {    /* into captlist */
  1847.                     fcnt=netread(ftpdata,xs,READSIZE);
  1848.                     if(fcnt>0) {        /* make certain a negative length string is not appended */
  1849.                         if(strlen(captlist)+fcnt>=2000) { /* full */
  1850.                             if(!fromtty || !n_scrlck())
  1851.                                 nputs(&xs[2001-strlen(captlist)]);    /* display excess chars */
  1852.                             strncat(captlist,xs,2000-strlen(captlist));
  1853.                             nputs("Error: capture list too long");
  1854.                             stopcapture=TRUE;
  1855.                           } /* end if */
  1856.                         else 
  1857.                             strncat(captlist,xs,fcnt);         /* append */
  1858.                       }    /* end if */
  1859. if(debug>2) {
  1860.     sprintf(printline,"xs %s fcnt %d ",xs,fcnt);
  1861.     nputs(printline);
  1862.     sprintf(printline,"tbytes %ld strlen(captlist) %d ",tbytes,strlen(captlist));
  1863.     nputs(printline);
  1864.   }
  1865.                   } /* end if */
  1866.                 else {
  1867.                     if(fromtty && n_scrlck())
  1868.                         break;    /* paused */
  1869.                     fcnt=netread(ftpdata,xs,READSIZE);
  1870.                     for(i=0; i<fcnt; i++) {
  1871.                         nputchar(xs[i]);    /* display */
  1872.                         if(xs[i]==10)
  1873.                             domore();          /* |more */
  1874.                       } /* end for */
  1875.                   } /* end else */
  1876.                 if(fcnt>0) 
  1877.                     tbytes+= fcnt;                     /* how much */
  1878.               } while(fcnt>0);                            /* till no more input */
  1879. if(debug>1) {
  1880.     sprintf(printline,"tbytes %ld ",tbytes);
  1881.     nputs(printline);
  1882.     sprintf(printline,"captlist %s ",captlist);
  1883.     nputs(printline);
  1884.   }
  1885.             break;
  1886.  
  1887.         case 30:        /* receive */
  1888.             if(!netest(ftpdata)) {        /* connection made */
  1889.                 start=time(NULL);
  1890.                 ftpstate=31;
  1891.                 len=xp=0;
  1892.                 tbytes=0;
  1893.               } /* end if */
  1894.             break;
  1895.  
  1896.         case 31:
  1897. /*
  1898. * file has already been opened, take everything from the connection
  1899. * and place into the open file: ftpfh
  1900. */
  1901.             do {        /* wait until xs is full before writing to disk */
  1902.                 if(len<=0) {
  1903.                     if(xp) {
  1904.                         if((write(ftpfh,xs,xp)==-1) && (errno==ENOSPC)) {
  1905.                             netwrite(ftpdata,"ABOR\r\n",6);    /* send abort */
  1906.                             netwrite(ftpdata,"452 Disk full error.\r\n",22);
  1907.                             printf("Local disk full error.\n");
  1908.                           } /* end if */
  1909.                         else
  1910.                             xp=0;
  1911.                       } /* end if */
  1912.                     len=BUFFERS;        /* expected or desired len to go */
  1913.                   } /* end if */
  1914. /* how much to read */
  1915.                 if(len<READSIZE)
  1916.                     i=len;
  1917.                 else
  1918.                     i=READSIZE;
  1919.                 fcnt=netread(ftpdata,&xs[xp],i);
  1920.                 if(fcnt>0) {    /* adjust counts */
  1921.                     len-=fcnt;
  1922.                     xp+=fcnt;
  1923.                     tbytes+=fcnt;
  1924.                   } /* end if */
  1925. if(debug>1) {
  1926.     sprintf(printline,"len %d xp %d fcnt %d",len,xp,fcnt);
  1927.     nputs(printline);
  1928.   }
  1929.                 if(fcnt<0) {                    /* connection closed */
  1930.                     write(ftpfh,xs,xp);            /* write last block */
  1931.                     if(ftpfilemode==FASCII) 
  1932.                         write(ftpfh,"\032",1);    /* EOF char */
  1933.                     close(ftpfh);
  1934.                     ftpfh=0;
  1935.                   } /* end if */
  1936.                 if(hash) {                        /* hash mark printing */
  1937.                     for(i=(int)(((tbytes-(long)fcnt)%1024L+(long)fcnt)/1024L); i; i--)
  1938.                         nputchar('#');
  1939.                   } /* end if */
  1940.               } while(fcnt>0);
  1941.             break;
  1942.  
  1943.         case 20:    /* send */
  1944.             if(!netest(ftpdata)) {                /* connection made */
  1945.                 start=time(NULL);
  1946.                 ftpstate=21;
  1947.                 lengthfile=lseek(ftpfh,0L,SEEK_END);   /* how long is file? */
  1948.                 lseek(ftpfh, -1L,SEEK_CUR);            /* position at last character*/
  1949.                 if(read(ftpfh, &lastchar, 1)==0) {
  1950. if(debug>4)
  1951.     printf("LC Test failed.\n");
  1952.                     lastchar='\0';
  1953.                   } /* end if */
  1954.                 else {
  1955. if(debug>4)
  1956.     printf("Last character test returned %d.\n",(int) lastchar);
  1957.                   } /* end else */
  1958.                 lseek(ftpfh,0L,SEEK_SET);               /* back to beginning */
  1959.                 if((ftpfilemode==FASCII) && (lastchar=='\26'))       /* drop cntr-Z for ascii transfer */
  1960.                     lengthfile--;                /* leave off ctrl-Z */
  1961.                 towrite=0;
  1962.                 xp=0;
  1963.                 tbytes=0;
  1964.               } /* end if */
  1965.             break;
  1966.  
  1967.         case 21:
  1968. /*
  1969. *  transfer file(s) to the other host via ftp request
  1970. *  file is already open=ftpfh
  1971. */
  1972. if(debug>4)
  1973.     printf("lengthfile=%d  towrite=%d  xp=%d  i=%d\n",lengthfile,towrite,xp,i);
  1974.  
  1975.             if(towrite<=xp) {            /* need to read again */
  1976. if(debug>4)
  1977.     printf("towrite<=xp\n");
  1978.                 if(lengthfile<(long)BUFFERS)
  1979.                     i=(int)lengthfile;
  1980.                 else
  1981.                     i=BUFFERS;
  1982. if(debug>4)
  1983.     printf("i=%d\n",i);
  1984.                 towrite=read(ftpfh,xs,i);
  1985. if(debug>4)
  1986.     printf("towrite=%d\n",towrite);
  1987.                 xp=0;
  1988.               } /* end if */
  1989.             if(towrite>=xp)
  1990.                 i=netwrite(ftpdata,&xs[xp],towrite-xp);
  1991.             else 
  1992.                 i=netwrite(ftpdata,&xs[xp],0);
  1993.             if(i>0) {                    /* send successful, adjust counts */
  1994.                 xp+=i;
  1995.                 lengthfile-=i;
  1996.                 tbytes+=i;
  1997.               } /* end if */
  1998. if(debug>1) {
  1999.     sprintf(printline,"i %d xp %d towrite %d",i,xp,towrite);
  2000.     nputs(printline);
  2001.   } /* end if */
  2002.             if(hash) {                    /* hash printing */
  2003.                 for(r1=(int)(((tbytes-(long)i)%1024L+(long)i)/1024L); r1; r1--)
  2004.                     nputchar('#');
  2005.               } /* end if */
  2006. /*
  2007. *  done if:  the file is all read from disk and all sent
  2008. *  or other side has ruined connection
  2009. */
  2010.             if((lengthfile<=0L && xp>=towrite) || netest(ftpdata))
  2011.                 ftpstate=22;
  2012.             break;
  2013.  
  2014.         case 22:            /* send done */
  2015. /* wait for other side to accept everything and then close */
  2016.             if(0>=(r1=netpush(ftpdata)))
  2017.                 fcnt=-1;
  2018. if(debug>1) {
  2019.     sprintf(printline,"fcnt %d r1 %d\n",fcnt,r1);
  2020.     nputs(printline);
  2021.   } /* end if */
  2022.             break;
  2023.  
  2024.       } /* end switch */
  2025. /*
  2026. *  after reading from connection, if the connection is closed,
  2027. *  reset up shop.
  2028. */
  2029.     if(fcnt<0) {        /* connection lost */
  2030.         if(ftpfh>0) {    /* close file */
  2031.             close(ftpfh);
  2032.             ftpfh=0;
  2033.           } /* end if */
  2034.         ftpstate=0;    /* done */
  2035.         fcnt=0;
  2036.         i=(int)(time(NULL)-start);    /* how long to transfer */
  2037.         if(!i) 
  2038.             rate=((double)tbytes)/1024.0;
  2039.         else 
  2040.             rate=((double)tbytes)/(i*1024.0);
  2041.         r1=(int)rate;              /* integer part of rate */
  2042.         r2=(int)((rate-(double)r1)*1000);
  2043.         sprintf(printline,"Transferred %ld bytes in %d seconds(%d.%03d Kbytes/sec)",tbytes,i,r1,r2);
  2044.         if(hash) 
  2045.             nputs("");
  2046.         if(verbose) 
  2047.             nputs(printline);
  2048.         netclose(ftpdata);            /* close connection */
  2049.         ftpdata=-1;
  2050.         if(bell) 
  2051.             nputchar(7);
  2052.       } /* end if */
  2053. }   /* end userftpd() */
  2054.  
  2055. /************************************************************************
  2056. * getword: remove a word from a string.  Things within quotes are
  2057. * assumed to be one word.
  2058. * return TRUE on success, FALSE on end of string
  2059. ************************************************************************/
  2060. static int getword(char *string,char *word)
  2061. {
  2062.     char *p,*q;
  2063.     int i=0;
  2064.  
  2065. if(debug>4) {
  2066.     sprintf(printline,"getword: string is %s",string);
  2067.     nputs(printline);
  2068.   }
  2069.     p=stpblk(string);            /* skip leading blanks */
  2070.     if(!(*p)) {                /* no words in string */
  2071.         word[0]='\0';
  2072.         return(FALSE);
  2073.       } /* end if */
  2074.     if(*p=='!') {                /*! is a word */
  2075.         word[0]=*p;
  2076.         word[1]='\0';
  2077.         strcpy(string,++p);
  2078.         return(TRUE);
  2079.       } /* end if */
  2080.     if(*p=='\"') {                /* word delimited by quotes */
  2081.         while(p[++i] && p[i]!='\"')
  2082.             word[i-1]=p[i];
  2083.         word[i-1]='\0';
  2084.         if(!p[i]) 
  2085.             nputs("Missing \". Assumed at end of string.");
  2086.         else 
  2087.             i++;
  2088.         q=p+i;
  2089.       } /* end if */
  2090.     else 
  2091.         q=stptok(p,word,50," \t\r\n");  /* get word, max len 50 */
  2092.     p=stpblk(q);                         /* remove trailing blanks */
  2093.     strcpy(string,p);                    /* remove extracted stuff */
  2094.     return(TRUE);
  2095. }   /* end getword() */
  2096.  
  2097. /************************************************************************/
  2098. /* flip_slashes: change \ to /                                            */
  2099. /************************************************************************/
  2100. static void flip_slashes(char *command,char *filename)
  2101. {
  2102.     int i;                 /* local counting variable */
  2103.  
  2104.     filename[0]='\0';                /* don't do anything with the filename */
  2105.     for(i=0; !command[i]; i++) {    /* loop over entire string */
  2106.         if(command[i]=='\\')         /* found a \ ? */
  2107.             command[i]='/';            /* flip the \ to a / */
  2108.       } /* end for */
  2109. }    /* end flip_slashes() */
  2110.  
  2111. /************************************************************************
  2112. * checkoredir: check for output redirection.  If the command contains a
  2113. * >, assume a filename follows and extract it.  Remove the redirection
  2114. * from the original command.
  2115. * Also change \ to /
  2116. * return TRUE if redirection specified, FALSE otherwise 
  2117. ************************************************************************/
  2118. static int checkoredir(char *command,char *filename,int slashflip)
  2119. {
  2120.     int i;
  2121.  
  2122.     filename[0]='\0';
  2123.     for(i=0; (command[i]!='>'); i++) {   /* process command part */
  2124.         if(command[i]=='\\' && slashflip)
  2125.             command[i]='/';
  2126.         if(!command[i]) 
  2127.             return(FALSE);                /* no redirection */
  2128.       } /* end for */
  2129.     getword(&command[i+1],filename);    /* get redirected filename */
  2130.     command[i]='\0';
  2131.     return(TRUE);
  2132. }   /* end checkoredir() */
  2133.  
  2134. /************************************************************************
  2135. * getdir: get current directory.  Finds current drive and current path
  2136. * on drive, returns a string.
  2137. *
  2138. ************************************************************************/
  2139. static void getdir(int drive,char *path)
  2140. {
  2141. #ifdef    MSC
  2142.     getcwd(path,100);
  2143.     drive=drive;            /* To get rid of annoying "Unreferenced formal parameter" warning. */
  2144. #else
  2145.     char partpath[64];
  2146.     if(!drive) drive=getdsk();                /* current disk */
  2147.         getcd(drive+1,partpath);            /* current dir */
  2148.     sprintf(path,"%c:\\%s",'A'+drive,partpath);
  2149. #endif
  2150. }   /* end getdir() */
  2151.  
  2152. /************************************************************************
  2153. * finduniq: find name that is a unique prefix of one of the entries in
  2154. * a list.  Return position of the entry, NONE if none, AMBIGUOUS if more
  2155. * than one.
  2156. *
  2157. ************************************************************************/
  2158. static int finduniq(char *name,char *list[],int listsize)
  2159. {
  2160.     int i,
  2161.         j=NONE,
  2162.         len;
  2163.  
  2164.     len=strlen(name);
  2165.     for(i=0; i<listsize; i++) {
  2166.         if(!strncmp(name,list[i],len)) {        /* prefix */
  2167.             if(len==(int)strlen(list[i]))
  2168.                 return(i+1);                    /* exact match */
  2169.             if(j!=NONE) 
  2170.                 j=AMBIGUOUS;                    /* more than one match */
  2171.             else
  2172.                 j=i+1;                              /* note prefix found */
  2173.           } /* end if */
  2174.       } /* end for */
  2175.     return(j);                                    /* prefix */
  2176. }   /* end finduniq() */
  2177.  
  2178. /************************************************************************
  2179. * checkevent
  2180. * get and process network events
  2181. * returns ABORT on user abort, HAVEDATA if data available on command
  2182. * connection, NONE if connection lost, DOMOK if domain search succeeds,
  2183. * DOMFAIL if domain search fails, TRUE if no relevant event.
  2184. ************************************************************************/
  2185. static int checkevent(void)
  2186. {
  2187.     int ev,
  2188.         class=0,
  2189.         data;
  2190.  
  2191.     kbhit();            /* check for cntrl-break */
  2192.     if(foundbreak)
  2193.         return(ABORT);
  2194.     userftpd();         /* do ftp stuff */
  2195.     Stask();            /* keep connections alive */
  2196.     ev=Sgetevent(CONCLASS|ERRCLASS|USERCLASS,&class,&data);
  2197.     if(class==CONCLASS) {
  2198.         if(data==ftpnum) {        /* command connection */
  2199.             if(ev==CONCLOSE) {    /* connection lost */
  2200.                 netclose(ftpnum);
  2201.                 if(!netest(ftpdata)) 
  2202.                     netclose(ftpdata);    /* close data connection */
  2203.                 connected=FALSE;
  2204.                 return(NONE);
  2205.               } /* end if */
  2206.             if(ev==CONDATA)
  2207.                 return(HAVEDATA);    /* data received */
  2208.           } /* end if */
  2209.       } /* end if */
  2210.     else 
  2211.         if(class==USERCLASS) {        
  2212.             if(ev==DOMOK) {        /* domain search succeeded */
  2213.                 ftpnum=data;
  2214.                 return(DOMOK);
  2215.               } /* end if */
  2216.             else 
  2217.                 if(ev==DOMFAIL) 
  2218.                     return(DOMFAIL);    /* domain search failed */
  2219.           } /* end if */
  2220.  
  2221. /* else if(class==ERRCLASS&&ev==ERR1) nputs(neterrstring(data)); */
  2222.     return(TRUE);
  2223. }   /* end checkevent() */
  2224.  
  2225. /************************************************************************
  2226. * putstring:
  2227. *   display string using vt100 emulation routines
  2228. ************************************************************************/
  2229. static int putstring(char *string)
  2230. {
  2231.     for(; *string; string++)
  2232.         nputchar(*string);
  2233.     return(TRUE);
  2234. }   /* end putstring() */
  2235.  
  2236. /************************************************************************
  2237. * printerr:
  2238. *   display TCP error messages-disabled
  2239. ************************************************************************/
  2240. static int printerr(void )
  2241. {
  2242. #ifdef OLD_WAY
  2243.     int data,class;
  2244.  
  2245.     while(ERR1==Sgetevent(ERRCLASS,&class,&data))
  2246.         nputs(neterrstring(data));
  2247. #endif
  2248.     return(TRUE);
  2249. }   /* end printerr() */
  2250.  
  2251. /************************************************************************
  2252. * getnname: get next name from captured list
  2253. * names delimited by newlines-<CR> or <LF>
  2254. ************************************************************************/
  2255. static int getnname(char *string,char *word)
  2256. {
  2257.     char *s;
  2258.  
  2259.     s=string;
  2260.     while((*string=='\n') || (*string=='\r'))
  2261.         string++;                        /* skip initial newlines */
  2262.     if(!(*string)) 
  2263.         return(FALSE);        /* end of captlist */
  2264.     while((*string!='\n') && (*string!='\r') && (*string))
  2265.         *(word++)=*(string++);
  2266.     while((*string=='\n') || (*string=='\r'))
  2267.         string++;    /* skip trailing newline */
  2268.     *word='\0';
  2269.     strcpy(s,string);
  2270.     return(TRUE);
  2271. }   /* end getnname() */
  2272.  
  2273. /***************************************************************************
  2274. *  dosescape
  2275. *  escape to dos for processing
  2276. *  put the connections to automated sleep while in DOS
  2277. ************************************************************************/
  2278. void dosescape(void)
  2279. {
  2280.     int i;
  2281.     char *command_shell;
  2282.  
  2283.     nputs("Warning, some programs will interfere with network communication and can");
  2284.     nputs("cause lost connections.  Do not run any network programs from this DOS shell.");
  2285.     nputs("Type 'EXIT' to return to FTP");
  2286. /*
  2287. *  invoke a put-to-sleep routine which calls netsleep every 8/18ths of a sec
  2288. */
  2289.     remove_break();
  2290.     tinst();
  2291.     command_shell=getenv("COMSPEC");
  2292.     if(command_shell!=NULL)
  2293.         i=system(command_shell);        /* call DOS */
  2294.      else
  2295.         i= -1;
  2296.     tdeinst();
  2297.     install_break(&foundbreak);
  2298.  
  2299.     if(i<0) {
  2300.         nputs("\n\nError loading COMMAND.COM");
  2301.         nputs("Make sure COMMAND.COM is specified under COMSPEC.");
  2302.         nputs("It must also be in a directory which is in your PATH statement.");
  2303.       } /* end if */
  2304.     if(fromtty) 
  2305.         n_row();
  2306. }   /* end dosescape() */
  2307.  
  2308. static void nputs(char *line)
  2309. {
  2310.     if(!scrsetup) {
  2311.         scrsetup=1;
  2312.         if(fromtty) {            /* don't do anything now */
  2313.             if(!display_init) {
  2314.                 Sgetconfig(&def);        /* get information provided in hosts file */
  2315.                 display_init=TRUE;
  2316.                 dos_color=n_color((int) def.color[0]);    /* set color to that set in config file */
  2317.               } /* end if */
  2318.             n_color((int) def.color[0]);    /* set color to that set in config file */
  2319.             n_clear();            /* clear screen */
  2320.             n_wrap(1);            /* cursor positioning */
  2321.             n_cur(0,0);
  2322.           } /* end if */
  2323.         puts("National Center for Supercomputing Applications");
  2324.         puts("        FTP version 2.3.05  3/15/91");
  2325.       } /* end if */
  2326.  
  2327.     if(*line) 
  2328.         puts(line);
  2329.     else 
  2330.         puts("");
  2331. }   /* end nputs() */
  2332.  
  2333. static void nputchar(char ch)
  2334. {
  2335.     if(fromtty && ttypass)
  2336.         putc(ch,stderr);
  2337.     else 
  2338.         putchar(ch);
  2339. }   /* end nputchar() */
  2340.  
  2341. #ifdef    MSC
  2342. static char *stptok(char *p,char *toword,int len,char *delim)
  2343. {
  2344.     char *adv=toword;
  2345.      int i;
  2346.      int end=0;
  2347.  
  2348.      do { 
  2349.         for(i=0; i<(int)strlen(delim); i++)
  2350.             if(*p==delim[i] || (!*p))
  2351.                 end++;
  2352.         if(!end) {
  2353.              if(adv>=(toword+len-1)) 
  2354.                 end++;
  2355.              *adv++=*p++;
  2356.           } /* end if */
  2357.       } while(!end);
  2358.      *adv='\0';
  2359.     return(p);
  2360. }   /* end stptok() */
  2361.  
  2362. static char *stpblk(char *ch)
  2363. {
  2364.     while(*ch==' ' || *ch=='\t')
  2365.         ch++;
  2366.     return(ch);
  2367. }   /* end stpblk() */
  2368. #endif
  2369.  
  2370. int domore(void)
  2371. {
  2372.     int ch=0;
  2373.  
  2374.     if(usemore) {
  2375.         if(lineslft--<=1) {
  2376.             printf("-- more --");
  2377.             ch=0;
  2378.             while(!ch) {
  2379.                 if(!kbhit())       /* if no char available */
  2380.                     Stask();        /* keep the connection alive */
  2381.                 else
  2382.                     ch=getch();   /* else get a character */
  2383.                 if(foundbreak) {
  2384.                     foundbreak=0;
  2385.                     ch=32;
  2386.                   } /* end if */
  2387.               } /* end while */
  2388.             printf("\r          \r");
  2389.             if(ch==13)
  2390.                 lineslft++;
  2391.             else
  2392.                 lineslft=numlines;
  2393.           } /* end if */
  2394.       } /* end if */
  2395.     return(ch);
  2396. }   /* end domore() */
  2397.  
  2398. /************************************************************************/
  2399. /*                             check_file_name                          */
  2400. /*                                                                      */
  2401. /*  A function to check for and enforce MS-DOS file name compatibility  */
  2402. /*  and uniqueness.  All non-MS-DOS filename characters from 'in_fname' */
  2403. /*  are deleted.  If the filename exists in the current directory, a    */
  2404. /*  unique name is created to avoid file name collision.                */
  2405. /*  'out_fname' must be large enough for the full filename (13 bytes).  */
  2406. /*                                                                      */
  2407. /*       Returns:    pointer to 'out_fname'                             */
  2408. /*                                                                      */
  2409. /*       Allen W. Todd                        Dec 24, 1990              */
  2410. /*                                                                      */
  2411. /************************************************************************/
  2412. char *check_file_name(char *in_fname,char *out_fname)
  2413. {
  2414.     char buf[80],
  2415.         *s,
  2416.         *fname,
  2417.         *fextn,
  2418.         num_buf[20];
  2419.     long count=0L;
  2420.  
  2421.     strcpy(buf,in_fname);    /* make local copy */
  2422.     strlwr(buf);              /* convert to lower case */
  2423.     while((s=strpbrk(buf, "\"*+,/:;<=>?[\]^|"))!=NULL)
  2424.         strcpy(s,s+1);        /* delete non-DOS chars */
  2425.     fname=&buf[0];           /* separate filename from file extension */
  2426.     if((fextn=strchr(buf,'.'))!=NULL)
  2427.         *fextn++='\0';
  2428.     if(strlen (fname)>8)
  2429.         *(fname+8)='\0';   /* fix filename @ 8 char */
  2430.     if(strlen(fextn)>3)
  2431.         *(fextn+3)='\0';   /* fix file extension @ 3 char */
  2432.     strcpy(out_fname,fname);     /* build complete filename */
  2433.     if(fextn) {
  2434.         strcat(out_fname,".");
  2435.         strcat(out_fname,fextn);
  2436.       } /* end if */
  2437.     while(access(out_fname,0)==0) {   /* if file already exists */
  2438.         ltoa(count++,num_buf,10);
  2439.         strcpy(out_fname,fname);     /* build complete filename */
  2440.         if((strlen(fextn)<3) && (strlen(num_buf)+strlen(fextn)<=3))
  2441.             strcat(fextn,num_buf);
  2442.         else {
  2443.             if(strlen(fname)>strlen(num_buf))
  2444.                 strcpy(out_fname+(strlen(fname)-strlen(num_buf)),num_buf);
  2445.             else
  2446.                 strcat(out_fname,num_buf);
  2447.           } /* end else */
  2448.         if(fextn) {
  2449.             strcat(out_fname,".");
  2450.             strcat(out_fname,fextn);
  2451.           } /* end if */
  2452.       } /* end while */
  2453.    return(out_fname);
  2454. }   /* end check_file_name() */
  2455.  
  2456.