121737Sdist /* 236942Skarels * Copyright (c) 1985, 1989 Regents of the University of California. 333737Sbostic * All rights reserved. 433737Sbostic * 533737Sbostic * Redistribution and use in source and binary forms are permitted 634901Sbostic * provided that the above copyright notice and this paragraph are 734901Sbostic * duplicated in all such forms and that any documentation, 834901Sbostic * advertising materials, and other materials related to such 934901Sbostic * distribution and use acknowledge that the software was developed 1034901Sbostic * by the University of California, Berkeley. The name of the 1134901Sbostic * University may not be used to endorse or promote products derived 1234901Sbostic * from this software without specific prior written permission. 1334901Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434901Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1536935Skarels * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621737Sdist */ 1721737Sdist 1810294Ssam #ifndef lint 19*37225Skarels static char sccsid[] = "@(#)cmds.c 5.16 (Berkeley) 03/21/89"; 2033737Sbostic #endif /* not lint */ 2110294Ssam 2210294Ssam /* 2310294Ssam * FTP User Program -- Command Routines. 2410294Ssam */ 2536940Skarels #include <sys/param.h> 2636940Skarels #include <sys/wait.h> 2736940Skarels #include <sys/stat.h> 2810294Ssam #include <sys/socket.h> 2910294Ssam 3012396Ssam #include <arpa/ftp.h> 3112396Ssam 3210294Ssam #include <signal.h> 3310294Ssam #include <stdio.h> 3410294Ssam #include <errno.h> 3510294Ssam #include <netdb.h> 3626049Sminshall #include <ctype.h> 3736935Skarels #include <time.h> 3810294Ssam 3936940Skarels #include "ftp_var.h" 4010294Ssam 4136940Skarels 4211353Ssam extern char *globerr; 4311353Ssam extern char **glob(); 4411756Ssam extern char *home; 4511756Ssam extern char *remglob(); 4611756Ssam extern char *getenv(); 4711756Ssam extern char *index(); 4811756Ssam extern char *rindex(); 4937224Skarels extern off_t restart_point; 5036935Skarels extern char reply_string[]; 5136935Skarels 5226049Sminshall char *mname; 5326049Sminshall jmp_buf jabort; 5426049Sminshall char *dotrans(), *domap(); 5510294Ssam 5610294Ssam /* 5710294Ssam * Connect to peer server and 5810294Ssam * auto-login, if possible. 5910294Ssam */ 6010294Ssam setpeer(argc, argv) 6110294Ssam int argc; 6210294Ssam char *argv[]; 6310294Ssam { 6425903Skarels char *host, *hookup(); 6510294Ssam int port; 6610294Ssam 6710294Ssam if (connected) { 6826049Sminshall printf("Already connected to %s, use close first.\n", 6910294Ssam hostname); 7026049Sminshall code = -1; 7110294Ssam return; 7210294Ssam } 7310294Ssam if (argc < 2) { 7426497Sminshall (void) strcat(line, " "); 7510294Ssam printf("(to) "); 7626497Sminshall (void) gets(&line[strlen(line)]); 7710294Ssam makeargv(); 7810294Ssam argc = margc; 7910294Ssam argv = margv; 8010294Ssam } 8110294Ssam if (argc > 3) { 8210294Ssam printf("usage: %s host-name [port]\n", argv[0]); 8326049Sminshall code = -1; 8410294Ssam return; 8510294Ssam } 8610294Ssam port = sp->s_port; 8710294Ssam if (argc > 2) { 8811218Ssam port = atoi(argv[2]); 8910294Ssam if (port <= 0) { 9011218Ssam printf("%s: bad port number-- %s\n", argv[1], argv[2]); 9111218Ssam printf ("usage: %s host-name [port]\n", argv[0]); 9226049Sminshall code = -1; 9310294Ssam return; 9410294Ssam } 9510294Ssam port = htons(port); 9610294Ssam } 9710294Ssam host = hookup(argv[1], port); 9810294Ssam if (host) { 9910294Ssam connected = 1; 10036935Skarels if (autologin) { 10136935Skarels int overbose; 10236940Skarels 10326497Sminshall (void) login(argv[1]); 10436935Skarels #if defined(unix) && NBBY == 8 10536935Skarels /* 10636935Skarels * this ifdef is to keep someone form "porting" this to an incompatible 10736935Skarels * system and not checking this out. This way they have to think about it. 10836935Skarels */ 10936940Skarels overbose = verbose; 11036940Skarels if (debug == 0) 11136940Skarels verbose = -1; 11236935Skarels if (command("SYST") == COMPLETE && overbose) { 11336935Skarels register char *cp, c; 11436935Skarels cp = index(reply_string+4, ' '); 11536935Skarels if (cp == NULL) 11636935Skarels cp = index(reply_string+4, '\r'); 11736935Skarels if (cp) { 11836935Skarels if (cp[-1] == '.') 11936935Skarels cp--; 12036935Skarels c = *cp; 12136935Skarels *cp = '\0'; 12236935Skarels } 12336935Skarels 12436935Skarels printf("Remote system type is %s.\n", 12536935Skarels reply_string+4); 12636935Skarels if (cp) 12736935Skarels *cp = c; 12836935Skarels } 12936935Skarels if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) { 13036935Skarels setbinary(); 13136935Skarels if (overbose) 13236940Skarels printf("Using %s mode to transfer files.\n", 13336940Skarels typename); 13436935Skarels } else if (overbose && 13536935Skarels !strncmp(reply_string, "215 TOPS20", 10)) { 13636940Skarels printf( 13736940Skarels "Remember to set tenex mode when transfering binary files from this machine.\n"); 13836935Skarels } 13936935Skarels verbose = overbose; 14036935Skarels #endif /* unix */ 14136935Skarels } 14210294Ssam } 14310294Ssam } 14410294Ssam 14510294Ssam struct types { 14610294Ssam char *t_name; 14710294Ssam char *t_mode; 14810294Ssam int t_type; 14911218Ssam char *t_arg; 15010294Ssam } types[] = { 15111218Ssam { "ascii", "A", TYPE_A, 0 }, 15211218Ssam { "binary", "I", TYPE_I, 0 }, 15311218Ssam { "image", "I", TYPE_I, 0 }, 15411218Ssam { "ebcdic", "E", TYPE_E, 0 }, 15511218Ssam { "tenex", "L", TYPE_L, bytename }, 15610294Ssam 0 15710294Ssam }; 15810294Ssam 15910294Ssam /* 16010294Ssam * Set transfer type. 16110294Ssam */ 16210294Ssam settype(argc, argv) 16310294Ssam char *argv[]; 16410294Ssam { 16510294Ssam register struct types *p; 16611218Ssam int comret; 16710294Ssam 16810294Ssam if (argc > 2) { 16910294Ssam char *sep; 17010294Ssam 17110294Ssam printf("usage: %s [", argv[0]); 17210294Ssam sep = " "; 17310294Ssam for (p = types; p->t_name; p++) { 17410294Ssam printf("%s%s", sep, p->t_name); 17510294Ssam if (*sep == ' ') 17610294Ssam sep = " | "; 17710294Ssam } 17810294Ssam printf(" ]\n"); 17926049Sminshall code = -1; 18010294Ssam return; 18110294Ssam } 18210294Ssam if (argc < 2) { 18310294Ssam printf("Using %s mode to transfer files.\n", typename); 18426049Sminshall code = 0; 18510294Ssam return; 18610294Ssam } 18710294Ssam for (p = types; p->t_name; p++) 18810294Ssam if (strcmp(argv[1], p->t_name) == 0) 18910294Ssam break; 19010294Ssam if (p->t_name == 0) { 19110294Ssam printf("%s: unknown mode\n", argv[1]); 19226049Sminshall code = -1; 19310294Ssam return; 19410294Ssam } 19511218Ssam if ((p->t_arg != NULL) && (*(p->t_arg) != '\0')) 19611218Ssam comret = command ("TYPE %s %s", p->t_mode, p->t_arg); 19711218Ssam else 19811218Ssam comret = command("TYPE %s", p->t_mode); 19911218Ssam if (comret == COMPLETE) { 20026497Sminshall (void) strcpy(typename, p->t_name); 20110294Ssam type = p->t_type; 20210294Ssam } 20310294Ssam } 20410294Ssam 20510294Ssam /* 20610294Ssam * Set binary transfer type. 20710294Ssam */ 20810294Ssam /*VARARGS*/ 20910294Ssam setbinary() 21010294Ssam { 21110294Ssam 21210294Ssam call(settype, "type", "binary", 0); 21310294Ssam } 21410294Ssam 21510294Ssam /* 21610294Ssam * Set ascii transfer type. 21710294Ssam */ 21810294Ssam /*VARARGS*/ 21910294Ssam setascii() 22010294Ssam { 22110294Ssam 22210294Ssam call(settype, "type", "ascii", 0); 22310294Ssam } 22410294Ssam 22510294Ssam /* 22610294Ssam * Set tenex transfer type. 22710294Ssam */ 22810294Ssam /*VARARGS*/ 22910294Ssam settenex() 23010294Ssam { 23110294Ssam 23210294Ssam call(settype, "type", "tenex", 0); 23310294Ssam } 23410294Ssam 23510294Ssam /* 23610294Ssam * Set ebcdic transfer type. 23710294Ssam */ 23810294Ssam /*VARARGS*/ 23910294Ssam setebcdic() 24010294Ssam { 24110294Ssam 24210294Ssam call(settype, "type", "ebcdic", 0); 24310294Ssam } 24410294Ssam 24510294Ssam /* 24610294Ssam * Set file transfer mode. 24710294Ssam */ 24826497Sminshall /*ARGSUSED*/ 24910294Ssam setmode(argc, argv) 25010294Ssam char *argv[]; 25110294Ssam { 25210294Ssam 25310294Ssam printf("We only support %s mode, sorry.\n", modename); 25426049Sminshall code = -1; 25510294Ssam } 25610294Ssam 25710294Ssam /* 25810294Ssam * Set file transfer format. 25910294Ssam */ 26026497Sminshall /*ARGSUSED*/ 26110294Ssam setform(argc, argv) 26210294Ssam char *argv[]; 26310294Ssam { 26410294Ssam 26510294Ssam printf("We only support %s format, sorry.\n", formname); 26626049Sminshall code = -1; 26710294Ssam } 26810294Ssam 26910294Ssam /* 27010294Ssam * Set file transfer structure. 27110294Ssam */ 27226497Sminshall /*ARGSUSED*/ 27310294Ssam setstruct(argc, argv) 27410294Ssam char *argv[]; 27510294Ssam { 27610294Ssam 27710294Ssam printf("We only support %s structure, sorry.\n", structname); 27826049Sminshall code = -1; 27910294Ssam } 28010294Ssam 28118286Sralph /* 28218286Sralph * Send a single file. 28318286Sralph */ 28410294Ssam put(argc, argv) 28511756Ssam int argc; 28610294Ssam char *argv[]; 28710294Ssam { 28811650Ssam char *cmd; 28926049Sminshall int loc = 0; 290*37225Skarels char *oldargv1, *oldargv2; 29111650Ssam 29226049Sminshall if (argc == 2) { 29326049Sminshall argc++; 29426049Sminshall argv[2] = argv[1]; 29526049Sminshall loc++; 29626049Sminshall } 29710294Ssam if (argc < 2) { 29826497Sminshall (void) strcat(line, " "); 29910294Ssam printf("(local-file) "); 30026497Sminshall (void) gets(&line[strlen(line)]); 30110294Ssam makeargv(); 30210294Ssam argc = margc; 30310294Ssam argv = margv; 30410294Ssam } 30510294Ssam if (argc < 2) { 30610294Ssam usage: 30726049Sminshall printf("usage:%s local-file remote-file\n", argv[0]); 30826049Sminshall code = -1; 30910294Ssam return; 31010294Ssam } 31110294Ssam if (argc < 3) { 31226497Sminshall (void) strcat(line, " "); 31310294Ssam printf("(remote-file) "); 31426497Sminshall (void) gets(&line[strlen(line)]); 31510294Ssam makeargv(); 31610294Ssam argc = margc; 31710294Ssam argv = margv; 31810294Ssam } 31910294Ssam if (argc < 3) 32010294Ssam goto usage; 32125908Smckusick oldargv1 = argv[1]; 322*37225Skarels oldargv2 = argv[2]; 32326049Sminshall if (!globulize(&argv[1])) { 32426049Sminshall code = -1; 32511353Ssam return; 32626049Sminshall } 32725908Smckusick /* 32825908Smckusick * If "globulize" modifies argv[1], and argv[2] is a copy of 32925908Smckusick * the old argv[1], make it a copy of the new argv[1]. 33025908Smckusick */ 33126049Sminshall if (argv[1] != oldargv1 && argv[2] == oldargv1) { 33225908Smckusick argv[2] = argv[1]; 33326049Sminshall } 33426049Sminshall cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR"); 33526049Sminshall if (loc && ntflag) { 33626049Sminshall argv[2] = dotrans(argv[2]); 33726049Sminshall } 33826049Sminshall if (loc && mapflag) { 33926049Sminshall argv[2] = domap(argv[2]); 34026049Sminshall } 341*37225Skarels sendrequest(cmd, argv[1], argv[2], 342*37225Skarels argv[1] != oldargv1 || argv[2] != oldargv2); 34310294Ssam } 34410294Ssam 34510294Ssam /* 34611756Ssam * Send multiple files. 34710294Ssam */ 34811353Ssam mput(argc, argv) 34911353Ssam char *argv[]; 35011353Ssam { 35113212Ssam register int i; 35226049Sminshall int ointer, (*oldintr)(), mabort(); 35326049Sminshall extern jmp_buf jabort; 35426049Sminshall char *tp; 35511353Ssam 35611650Ssam if (argc < 2) { 35726497Sminshall (void) strcat(line, " "); 35811650Ssam printf("(local-files) "); 35926497Sminshall (void) gets(&line[strlen(line)]); 36011650Ssam makeargv(); 36111650Ssam argc = margc; 36211650Ssam argv = margv; 36311353Ssam } 36411353Ssam if (argc < 2) { 36526049Sminshall printf("usage:%s local-files\n", argv[0]); 36626049Sminshall code = -1; 36711353Ssam return; 36811353Ssam } 36926049Sminshall mname = argv[0]; 37026049Sminshall mflag = 1; 37126049Sminshall oldintr = signal(SIGINT, mabort); 37226049Sminshall (void) setjmp(jabort); 37326049Sminshall if (proxy) { 37426049Sminshall char *cp, *tp2, tmpbuf[MAXPATHLEN]; 37526049Sminshall 37626497Sminshall while ((cp = remglob(argv,0)) != NULL) { 37726049Sminshall if (*cp == 0) { 37826049Sminshall mflag = 0; 37926049Sminshall continue; 38026049Sminshall } 38126049Sminshall if (mflag && confirm(argv[0], cp)) { 38226049Sminshall tp = cp; 38326049Sminshall if (mcase) { 38426049Sminshall while (*tp && !islower(*tp)) { 38526049Sminshall tp++; 38626049Sminshall } 38726049Sminshall if (!*tp) { 38826049Sminshall tp = cp; 38926049Sminshall tp2 = tmpbuf; 39026049Sminshall while ((*tp2 = *tp) != NULL) { 39126049Sminshall if (isupper(*tp2)) { 39226049Sminshall *tp2 = 'a' + *tp2 - 'A'; 39326049Sminshall } 39426049Sminshall tp++; 39526049Sminshall tp2++; 39626049Sminshall } 39726049Sminshall } 39826049Sminshall tp = tmpbuf; 39926049Sminshall } 40026049Sminshall if (ntflag) { 40126049Sminshall tp = dotrans(tp); 40226049Sminshall } 40326049Sminshall if (mapflag) { 40426049Sminshall tp = domap(tp); 40526049Sminshall } 406*37225Skarels sendrequest((sunique) ? "STOU" : "STOR", 407*37225Skarels cp, tp, cp != tp || !interactive); 40826049Sminshall if (!mflag && fromatty) { 40926049Sminshall ointer = interactive; 41026049Sminshall interactive = 1; 41126049Sminshall if (confirm("Continue with","mput")) { 41226049Sminshall mflag++; 41326049Sminshall } 41426049Sminshall interactive = ointer; 41526049Sminshall } 41626049Sminshall } 41726049Sminshall } 41826049Sminshall (void) signal(SIGINT, oldintr); 41926049Sminshall mflag = 0; 42026049Sminshall return; 42126049Sminshall } 42213212Ssam for (i = 1; i < argc; i++) { 42313212Ssam register char **cpp, **gargs; 42413212Ssam 42513212Ssam if (!doglob) { 42626049Sminshall if (mflag && confirm(argv[0], argv[i])) { 42726049Sminshall tp = (ntflag) ? dotrans(argv[i]) : argv[i]; 42826049Sminshall tp = (mapflag) ? domap(tp) : tp; 42926049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 430*37225Skarels argv[i], tp, tp != argv[i] || !interactive); 43126049Sminshall if (!mflag && fromatty) { 43226049Sminshall ointer = interactive; 43326049Sminshall interactive = 1; 43426049Sminshall if (confirm("Continue with","mput")) { 43526049Sminshall mflag++; 43626049Sminshall } 43726049Sminshall interactive = ointer; 43826049Sminshall } 43926049Sminshall } 44013212Ssam continue; 44113212Ssam } 44213212Ssam gargs = glob(argv[i]); 44311650Ssam if (globerr != NULL) { 44411650Ssam printf("%s\n", globerr); 44536421Sbostic if (gargs) { 44611650Ssam blkfree(gargs); 44736421Sbostic free(gargs); 44836421Sbostic } 44913212Ssam continue; 45011353Ssam } 45126049Sminshall for (cpp = gargs; cpp && *cpp != NULL; cpp++) { 45226049Sminshall if (mflag && confirm(argv[0], *cpp)) { 45326049Sminshall tp = (ntflag) ? dotrans(*cpp) : *cpp; 45426049Sminshall tp = (mapflag) ? domap(tp) : tp; 45526049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 456*37225Skarels *cpp, tp, *cpp != tp || !interactive); 45726049Sminshall if (!mflag && fromatty) { 45826049Sminshall ointer = interactive; 45926049Sminshall interactive = 1; 46026049Sminshall if (confirm("Continue with","mput")) { 46126049Sminshall mflag++; 46226049Sminshall } 46326049Sminshall interactive = ointer; 46426049Sminshall } 46526049Sminshall } 46626049Sminshall } 46736421Sbostic if (gargs != NULL) { 46813212Ssam blkfree(gargs); 46936421Sbostic free(gargs); 47036421Sbostic } 47111353Ssam } 47226049Sminshall (void) signal(SIGINT, oldintr); 47326049Sminshall mflag = 0; 47411353Ssam } 47511353Ssam 47637224Skarels reget(argc, argv) 47737224Skarels char *argv[]; 47837224Skarels { 47937224Skarels (void) getit(argc, argv, 1, "r+w"); 48037224Skarels } 48136935Skarels 48237224Skarels get(argc, argv) 48337224Skarels char *argv[]; 48437224Skarels { 48537224Skarels (void) getit(argc, argv, 0, restart_point ? "r+w" : "w" ); 48637224Skarels } 48737224Skarels 48811353Ssam /* 48911353Ssam * Receive one file. 49011353Ssam */ 49137224Skarels getit(argc, argv, restartit, mode) 49210294Ssam char *argv[]; 49337224Skarels char *mode; 49410294Ssam { 49526049Sminshall int loc = 0; 496*37225Skarels char *oldargv1, *oldargv2; 49710294Ssam 49826049Sminshall if (argc == 2) { 49926049Sminshall argc++; 50026049Sminshall argv[2] = argv[1]; 50126049Sminshall loc++; 50226049Sminshall } 50310294Ssam if (argc < 2) { 50426497Sminshall (void) strcat(line, " "); 50510294Ssam printf("(remote-file) "); 50626497Sminshall (void) gets(&line[strlen(line)]); 50710294Ssam makeargv(); 50810294Ssam argc = margc; 50910294Ssam argv = margv; 51010294Ssam } 51110294Ssam if (argc < 2) { 51210294Ssam usage: 51326049Sminshall printf("usage: %s remote-file [ local-file ]\n", argv[0]); 51426049Sminshall code = -1; 51537224Skarels return (0); 51610294Ssam } 51710294Ssam if (argc < 3) { 51826497Sminshall (void) strcat(line, " "); 51910294Ssam printf("(local-file) "); 52026497Sminshall (void) gets(&line[strlen(line)]); 52110294Ssam makeargv(); 52210294Ssam argc = margc; 52310294Ssam argv = margv; 52410294Ssam } 52510294Ssam if (argc < 3) 52610294Ssam goto usage; 527*37225Skarels oldargv1 = argv[1]; 528*37225Skarels oldargv2 = argv[2]; 52926049Sminshall if (!globulize(&argv[2])) { 53026049Sminshall code = -1; 53137224Skarels return (0); 53226049Sminshall } 53326049Sminshall if (loc && mcase) { 53426049Sminshall char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN]; 53526049Sminshall 53626049Sminshall while (*tp && !islower(*tp)) { 53726049Sminshall tp++; 53826049Sminshall } 53926049Sminshall if (!*tp) { 54026049Sminshall tp = argv[2]; 54126049Sminshall tp2 = tmpbuf; 54226049Sminshall while ((*tp2 = *tp) != NULL) { 54326049Sminshall if (isupper(*tp2)) { 54426049Sminshall *tp2 = 'a' + *tp2 - 'A'; 54526049Sminshall } 54626049Sminshall tp++; 54726049Sminshall tp2++; 54826049Sminshall } 54926049Sminshall argv[2] = tmpbuf; 55026049Sminshall } 55126049Sminshall } 55236940Skarels if (loc && ntflag) 55326049Sminshall argv[2] = dotrans(argv[2]); 55436940Skarels if (loc && mapflag) 55526049Sminshall argv[2] = domap(argv[2]); 55637224Skarels if (restartit) { 55737224Skarels struct stat stbuf; 55837224Skarels int ret; 55937224Skarels 56037224Skarels ret = stat(argv[2], &stbuf); 56137224Skarels if (restartit == 1) { 56237224Skarels if (ret < 0) { 56337224Skarels perror(argv[2]); 56437224Skarels return (0); 56537224Skarels } 56637224Skarels restart_point = stbuf.st_size; 56737224Skarels } else { 56837224Skarels if (ret == 0) { 56937224Skarels int overbose; 57037224Skarels 57137224Skarels overbose = verbose; 57237224Skarels if (debug == 0) 57337224Skarels verbose = -1; 57437224Skarels if (command("MDTM %s", argv[1]) == COMPLETE) { 57537224Skarels int yy, mo, day, hour, min, sec; 57637224Skarels struct tm *tm; 57737224Skarels verbose = overbose; 57837224Skarels sscanf(reply_string, 57937224Skarels "%*s %04d%02d%02d%02d%02d%02d", 58037224Skarels &yy, &mo, &day, &hour, &min, &sec); 58137224Skarels tm = gmtime(&stbuf.st_mtime); 58237224Skarels tm->tm_mon++; 58337224Skarels if (tm->tm_year > yy%100) 58437224Skarels return (1); 58537224Skarels else if (tm->tm_year == yy%100) { 58637224Skarels if (tm->tm_mon > mo) 58737224Skarels return (1); 58837224Skarels } else if (tm->tm_mon == mo) { 58937224Skarels if (tm->tm_mday > day) 59037224Skarels return (1); 59137224Skarels } else if (tm->tm_mday == day) { 59237224Skarels if (tm->tm_hour > hour) 59337224Skarels return (1); 59437224Skarels } else if (tm->tm_hour == hour) { 59537224Skarels if (tm->tm_min > min) 59637224Skarels return (1); 59737224Skarels } else if (tm->tm_min == min) { 59837224Skarels if (tm->tm_sec > sec) 59937224Skarels return (1); 60037224Skarels } 60137224Skarels } else { 60237224Skarels fputs(reply_string, stdout); 60337224Skarels verbose = overbose; 60437224Skarels return (0); 60537224Skarels } 60637224Skarels } 60737224Skarels } 60837224Skarels } 60937224Skarels 610*37225Skarels recvrequest("RETR", argv[2], argv[1], mode, 611*37225Skarels argv[1] != oldargv1 || argv[2] != oldargv2); 61237224Skarels restart_point = 0; 61337224Skarels return (0); 61410294Ssam } 61510294Ssam 61626049Sminshall mabort() 61726049Sminshall { 61826049Sminshall int ointer; 61926049Sminshall extern jmp_buf jabort; 62026049Sminshall 62126049Sminshall printf("\n"); 62226049Sminshall (void) fflush(stdout); 62326049Sminshall if (mflag && fromatty) { 62426049Sminshall ointer = interactive; 62526049Sminshall interactive = 1; 62626049Sminshall if (confirm("Continue with", mname)) { 62726049Sminshall interactive = ointer; 62826049Sminshall longjmp(jabort,0); 62926049Sminshall } 63026049Sminshall interactive = ointer; 63126049Sminshall } 63226049Sminshall mflag = 0; 63326049Sminshall longjmp(jabort,0); 63426049Sminshall } 63526049Sminshall 63611353Ssam /* 63711353Ssam * Get multiple files. 63811353Ssam */ 63911353Ssam mget(argc, argv) 64011353Ssam char *argv[]; 64111353Ssam { 64226049Sminshall char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN]; 64326049Sminshall int ointer, (*oldintr)(), mabort(); 64426049Sminshall extern jmp_buf jabort; 64511353Ssam 64611353Ssam if (argc < 2) { 64726497Sminshall (void) strcat(line, " "); 64811756Ssam printf("(remote-files) "); 64926497Sminshall (void) gets(&line[strlen(line)]); 65011353Ssam makeargv(); 65111353Ssam argc = margc; 65211353Ssam argv = margv; 65311353Ssam } 65411353Ssam if (argc < 2) { 65526049Sminshall printf("usage:%s remote-files\n", argv[0]); 65626049Sminshall code = -1; 65711353Ssam return; 65811353Ssam } 65926049Sminshall mname = argv[0]; 66026049Sminshall mflag = 1; 66126049Sminshall oldintr = signal(SIGINT,mabort); 66226049Sminshall (void) setjmp(jabort); 66326497Sminshall while ((cp = remglob(argv,proxy)) != NULL) { 66426049Sminshall if (*cp == '\0') { 66526049Sminshall mflag = 0; 66626049Sminshall continue; 66726049Sminshall } 66826049Sminshall if (mflag && confirm(argv[0], cp)) { 66926049Sminshall tp = cp; 67026049Sminshall if (mcase) { 67126049Sminshall while (*tp && !islower(*tp)) { 67226049Sminshall tp++; 67326049Sminshall } 67426049Sminshall if (!*tp) { 67526049Sminshall tp = cp; 67626049Sminshall tp2 = tmpbuf; 67726049Sminshall while ((*tp2 = *tp) != NULL) { 67826049Sminshall if (isupper(*tp2)) { 67926049Sminshall *tp2 = 'a' + *tp2 - 'A'; 68026049Sminshall } 68126049Sminshall tp++; 68226049Sminshall tp2++; 68326049Sminshall } 68426049Sminshall } 68526049Sminshall tp = tmpbuf; 68626049Sminshall } 68726049Sminshall if (ntflag) { 68826049Sminshall tp = dotrans(tp); 68926049Sminshall } 69026049Sminshall if (mapflag) { 69126049Sminshall tp = domap(tp); 69226049Sminshall } 693*37225Skarels recvrequest("RETR", tp, cp, "w", 694*37225Skarels tp != cp || !interactive); 69526049Sminshall if (!mflag && fromatty) { 69626049Sminshall ointer = interactive; 69726049Sminshall interactive = 1; 69826049Sminshall if (confirm("Continue with","mget")) { 69926049Sminshall mflag++; 70026049Sminshall } 70126049Sminshall interactive = ointer; 70226049Sminshall } 70326049Sminshall } 70426049Sminshall } 70526049Sminshall (void) signal(SIGINT,oldintr); 70626049Sminshall mflag = 0; 70711650Ssam } 70811650Ssam 70911650Ssam char * 71026497Sminshall remglob(argv,doswitch) 71111650Ssam char *argv[]; 71226497Sminshall int doswitch; 71311650Ssam { 71411756Ssam char temp[16]; 71511650Ssam static char buf[MAXPATHLEN]; 71611650Ssam static FILE *ftemp = NULL; 71711650Ssam static char **args; 71813212Ssam int oldverbose, oldhash; 71911756Ssam char *cp, *mode; 72011650Ssam 72126049Sminshall if (!mflag) { 72226049Sminshall if (!doglob) { 72326049Sminshall args = NULL; 72426049Sminshall } 72526049Sminshall else { 72626049Sminshall if (ftemp) { 72726497Sminshall (void) fclose(ftemp); 72826049Sminshall ftemp = NULL; 72926049Sminshall } 73026049Sminshall } 73126049Sminshall return(NULL); 73226049Sminshall } 73311650Ssam if (!doglob) { 73411756Ssam if (args == NULL) 73511650Ssam args = argv; 73611650Ssam if ((cp = *++args) == NULL) 73711650Ssam args = NULL; 73811650Ssam return (cp); 73911353Ssam } 74011650Ssam if (ftemp == NULL) { 74126497Sminshall (void) strcpy(temp, "/tmp/ftpXXXXXX"); 74226497Sminshall (void) mktemp(temp); 74311650Ssam oldverbose = verbose, verbose = 0; 74413212Ssam oldhash = hash, hash = 0; 74526049Sminshall if (doswitch) { 74626049Sminshall pswitch(!proxy); 74726049Sminshall } 74811756Ssam for (mode = "w"; *++argv != NULL; mode = "a") 749*37225Skarels recvrequest ("NLST", temp, *argv, mode, 0); 75026049Sminshall if (doswitch) { 75126049Sminshall pswitch(!proxy); 75226049Sminshall } 75313212Ssam verbose = oldverbose; hash = oldhash; 75411650Ssam ftemp = fopen(temp, "r"); 75526497Sminshall (void) unlink(temp); 75611650Ssam if (ftemp == NULL) { 75711650Ssam printf("can't find list of remote files, oops\n"); 75811756Ssam return (NULL); 75911353Ssam } 76011353Ssam } 76111650Ssam if (fgets(buf, sizeof (buf), ftemp) == NULL) { 76226497Sminshall (void) fclose(ftemp), ftemp = NULL; 76311650Ssam return (NULL); 76411353Ssam } 76511650Ssam if ((cp = index(buf, '\n')) != NULL) 76611650Ssam *cp = '\0'; 76711650Ssam return (buf); 76811353Ssam } 76911353Ssam 77010294Ssam char * 77110294Ssam onoff(bool) 77210294Ssam int bool; 77310294Ssam { 77410294Ssam 77510294Ssam return (bool ? "on" : "off"); 77610294Ssam } 77710294Ssam 77810294Ssam /* 77910294Ssam * Show status. 78010294Ssam */ 78126497Sminshall /*ARGSUSED*/ 78210294Ssam status(argc, argv) 78310294Ssam char *argv[]; 78410294Ssam { 78526049Sminshall int i; 78610294Ssam 78710294Ssam if (connected) 78810294Ssam printf("Connected to %s.\n", hostname); 78910294Ssam else 79010294Ssam printf("Not connected.\n"); 79126049Sminshall if (!proxy) { 79226049Sminshall pswitch(1); 79326049Sminshall if (connected) { 79426049Sminshall printf("Connected for proxy commands to %s.\n", hostname); 79526049Sminshall } 79626049Sminshall else { 79726049Sminshall printf("No proxy connection.\n"); 79826049Sminshall } 79926049Sminshall pswitch(0); 80026049Sminshall } 80110294Ssam printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n", 80210294Ssam modename, typename, formname, structname); 80311353Ssam printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 80411353Ssam onoff(verbose), onoff(bell), onoff(interactive), 80511353Ssam onoff(doglob)); 80626049Sminshall printf("Store unique: %s; Receive unique: %s\n", onoff(sunique), 80726049Sminshall onoff(runique)); 80826049Sminshall printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag)); 80926049Sminshall if (ntflag) { 81026049Sminshall printf("Ntrans: (in) %s (out) %s\n", ntin,ntout); 81126049Sminshall } 81226049Sminshall else { 81326049Sminshall printf("Ntrans: off\n"); 81426049Sminshall } 81526049Sminshall if (mapflag) { 81626049Sminshall printf("Nmap: (in) %s (out) %s\n", mapin, mapout); 81726049Sminshall } 81826049Sminshall else { 81926049Sminshall printf("Nmap: off\n"); 82026049Sminshall } 82114143Ssam printf("Hash mark printing: %s; Use of PORT cmds: %s\n", 82214143Ssam onoff(hash), onoff(sendport)); 82326049Sminshall if (macnum > 0) { 82426049Sminshall printf("Macros:\n"); 82526049Sminshall for (i=0; i<macnum; i++) { 82626049Sminshall printf("\t%s\n",macros[i].mac_name); 82726049Sminshall } 82826049Sminshall } 82926049Sminshall code = 0; 83010294Ssam } 83110294Ssam 83210294Ssam /* 83310294Ssam * Set beep on cmd completed mode. 83410294Ssam */ 83510294Ssam /*VARARGS*/ 83610294Ssam setbell() 83710294Ssam { 83810294Ssam 83910294Ssam bell = !bell; 84010294Ssam printf("Bell mode %s.\n", onoff(bell)); 84126049Sminshall code = bell; 84210294Ssam } 84310294Ssam 84410294Ssam /* 84510294Ssam * Turn on packet tracing. 84610294Ssam */ 84710294Ssam /*VARARGS*/ 84810294Ssam settrace() 84910294Ssam { 85010294Ssam 85110294Ssam trace = !trace; 85210294Ssam printf("Packet tracing %s.\n", onoff(trace)); 85326049Sminshall code = trace; 85410294Ssam } 85510294Ssam 85610294Ssam /* 85711650Ssam * Toggle hash mark printing during transfers. 85811650Ssam */ 85911650Ssam /*VARARGS*/ 86011650Ssam sethash() 86111650Ssam { 86211650Ssam 86311650Ssam hash = !hash; 86411650Ssam printf("Hash mark printing %s", onoff(hash)); 86526049Sminshall code = hash; 86611650Ssam if (hash) 86737224Skarels printf(" (%d bytes/hash mark)", 1024); 86811650Ssam printf(".\n"); 86911650Ssam } 87011650Ssam 87111650Ssam /* 87210294Ssam * Turn on printing of server echo's. 87310294Ssam */ 87410294Ssam /*VARARGS*/ 87510294Ssam setverbose() 87610294Ssam { 87710294Ssam 87810294Ssam verbose = !verbose; 87910294Ssam printf("Verbose mode %s.\n", onoff(verbose)); 88026049Sminshall code = verbose; 88110294Ssam } 88210294Ssam 88310294Ssam /* 88411650Ssam * Toggle PORT cmd use before each data connection. 88511650Ssam */ 88611650Ssam /*VARARGS*/ 88711650Ssam setport() 88811650Ssam { 88911650Ssam 89011650Ssam sendport = !sendport; 89111650Ssam printf("Use of PORT cmds %s.\n", onoff(sendport)); 89226049Sminshall code = sendport; 89311650Ssam } 89411650Ssam 89511650Ssam /* 89610294Ssam * Turn on interactive prompting 89710294Ssam * during mget, mput, and mdelete. 89810294Ssam */ 89910294Ssam /*VARARGS*/ 90010294Ssam setprompt() 90110294Ssam { 90210294Ssam 90310294Ssam interactive = !interactive; 90410294Ssam printf("Interactive mode %s.\n", onoff(interactive)); 90526049Sminshall code = interactive; 90610294Ssam } 90710294Ssam 90810294Ssam /* 90911353Ssam * Toggle metacharacter interpretation 91011353Ssam * on local file names. 91111353Ssam */ 91211353Ssam /*VARARGS*/ 91311353Ssam setglob() 91411353Ssam { 91511353Ssam 91611353Ssam doglob = !doglob; 91711353Ssam printf("Globbing %s.\n", onoff(doglob)); 91826049Sminshall code = doglob; 91911353Ssam } 92011353Ssam 92111353Ssam /* 92210294Ssam * Set debugging mode on/off and/or 92310294Ssam * set level of debugging. 92410294Ssam */ 92511756Ssam /*VARARGS*/ 92610294Ssam setdebug(argc, argv) 92710294Ssam char *argv[]; 92810294Ssam { 92910294Ssam int val; 93010294Ssam 93110294Ssam if (argc > 1) { 93210294Ssam val = atoi(argv[1]); 93310294Ssam if (val < 0) { 93410294Ssam printf("%s: bad debugging value.\n", argv[1]); 93526049Sminshall code = -1; 93610294Ssam return; 93710294Ssam } 93810294Ssam } else 93910294Ssam val = !debug; 94010294Ssam debug = val; 94110294Ssam if (debug) 94210294Ssam options |= SO_DEBUG; 94310294Ssam else 94410294Ssam options &= ~SO_DEBUG; 94510294Ssam printf("Debugging %s (debug=%d).\n", onoff(debug), debug); 94626049Sminshall code = debug > 0; 94710294Ssam } 94810294Ssam 94910294Ssam /* 95010294Ssam * Set current working directory 95110294Ssam * on remote machine. 95210294Ssam */ 95310294Ssam cd(argc, argv) 95410294Ssam char *argv[]; 95510294Ssam { 95610294Ssam 95710294Ssam if (argc < 2) { 95826497Sminshall (void) strcat(line, " "); 95910294Ssam printf("(remote-directory) "); 96026497Sminshall (void) gets(&line[strlen(line)]); 96110294Ssam makeargv(); 96210294Ssam argc = margc; 96310294Ssam argv = margv; 96410294Ssam } 96510294Ssam if (argc < 2) { 96626049Sminshall printf("usage:%s remote-directory\n", argv[0]); 96726049Sminshall code = -1; 96810294Ssam return; 96910294Ssam } 97037224Skarels if (command("CWD %s", argv[1]) == ERROR && code == 500) { 97137224Skarels if (verbose) 97237224Skarels printf("CWD command not recognized, trying XCWD\n"); 97337224Skarels (void) command("XCWD %s", argv[1]); 97437224Skarels } 97510294Ssam } 97610294Ssam 97710294Ssam /* 97810294Ssam * Set current working directory 97910294Ssam * on local machine. 98010294Ssam */ 98110294Ssam lcd(argc, argv) 98210294Ssam char *argv[]; 98310294Ssam { 98411353Ssam char buf[MAXPATHLEN]; 98510294Ssam 98611353Ssam if (argc < 2) 98711353Ssam argc++, argv[1] = home; 98810294Ssam if (argc != 2) { 98926049Sminshall printf("usage:%s local-directory\n", argv[0]); 99026049Sminshall code = -1; 99110294Ssam return; 99210294Ssam } 99326049Sminshall if (!globulize(&argv[1])) { 99426049Sminshall code = -1; 99511353Ssam return; 99626049Sminshall } 99711353Ssam if (chdir(argv[1]) < 0) { 99810294Ssam perror(argv[1]); 99926049Sminshall code = -1; 100011353Ssam return; 100111353Ssam } 100211353Ssam printf("Local directory now %s\n", getwd(buf)); 100326049Sminshall code = 0; 100410294Ssam } 100510294Ssam 100610294Ssam /* 100710294Ssam * Delete a single file. 100810294Ssam */ 100910294Ssam delete(argc, argv) 101010294Ssam char *argv[]; 101110294Ssam { 101210294Ssam 101310294Ssam if (argc < 2) { 101426497Sminshall (void) strcat(line, " "); 101510294Ssam printf("(remote-file) "); 101626497Sminshall (void) gets(&line[strlen(line)]); 101710294Ssam makeargv(); 101810294Ssam argc = margc; 101910294Ssam argv = margv; 102010294Ssam } 102110294Ssam if (argc < 2) { 102226049Sminshall printf("usage:%s remote-file\n", argv[0]); 102326049Sminshall code = -1; 102410294Ssam return; 102510294Ssam } 102610294Ssam (void) command("DELE %s", argv[1]); 102710294Ssam } 102810294Ssam 102910294Ssam /* 103011650Ssam * Delete multiple files. 103111650Ssam */ 103211650Ssam mdelete(argc, argv) 103311650Ssam char *argv[]; 103411650Ssam { 103511650Ssam char *cp; 103626049Sminshall int ointer, (*oldintr)(), mabort(); 103726049Sminshall extern jmp_buf jabort; 103811650Ssam 103911650Ssam if (argc < 2) { 104026497Sminshall (void) strcat(line, " "); 104111650Ssam printf("(remote-files) "); 104226497Sminshall (void) gets(&line[strlen(line)]); 104311650Ssam makeargv(); 104411650Ssam argc = margc; 104511650Ssam argv = margv; 104611650Ssam } 104711650Ssam if (argc < 2) { 104826049Sminshall printf("usage:%s remote-files\n", argv[0]); 104926049Sminshall code = -1; 105011650Ssam return; 105111650Ssam } 105226049Sminshall mname = argv[0]; 105326049Sminshall mflag = 1; 105426049Sminshall oldintr = signal(SIGINT, mabort); 105526049Sminshall (void) setjmp(jabort); 105626497Sminshall while ((cp = remglob(argv,0)) != NULL) { 105726049Sminshall if (*cp == '\0') { 105826049Sminshall mflag = 0; 105926049Sminshall continue; 106026049Sminshall } 106126049Sminshall if (mflag && confirm(argv[0], cp)) { 106211650Ssam (void) command("DELE %s", cp); 106326049Sminshall if (!mflag && fromatty) { 106426049Sminshall ointer = interactive; 106526049Sminshall interactive = 1; 106626049Sminshall if (confirm("Continue with", "mdelete")) { 106726049Sminshall mflag++; 106826049Sminshall } 106926049Sminshall interactive = ointer; 107026049Sminshall } 107126049Sminshall } 107226049Sminshall } 107326049Sminshall (void) signal(SIGINT, oldintr); 107426049Sminshall mflag = 0; 107511650Ssam } 107611756Ssam 107711650Ssam /* 107810294Ssam * Rename a remote file. 107910294Ssam */ 108010294Ssam renamefile(argc, argv) 108110294Ssam char *argv[]; 108210294Ssam { 108310294Ssam 108410294Ssam if (argc < 2) { 108526497Sminshall (void) strcat(line, " "); 108610294Ssam printf("(from-name) "); 108726497Sminshall (void) gets(&line[strlen(line)]); 108810294Ssam makeargv(); 108910294Ssam argc = margc; 109010294Ssam argv = margv; 109110294Ssam } 109210294Ssam if (argc < 2) { 109310294Ssam usage: 109410294Ssam printf("%s from-name to-name\n", argv[0]); 109526049Sminshall code = -1; 109610294Ssam return; 109710294Ssam } 109810294Ssam if (argc < 3) { 109926497Sminshall (void) strcat(line, " "); 110010294Ssam printf("(to-name) "); 110126497Sminshall (void) gets(&line[strlen(line)]); 110210294Ssam makeargv(); 110310294Ssam argc = margc; 110410294Ssam argv = margv; 110510294Ssam } 110610294Ssam if (argc < 3) 110710294Ssam goto usage; 110810294Ssam if (command("RNFR %s", argv[1]) == CONTINUE) 110910294Ssam (void) command("RNTO %s", argv[2]); 111010294Ssam } 111110294Ssam 111210294Ssam /* 111310294Ssam * Get a directory listing 111410294Ssam * of remote files. 111510294Ssam */ 111610294Ssam ls(argc, argv) 111710294Ssam char *argv[]; 111810294Ssam { 111911756Ssam char *cmd; 112010294Ssam 112110294Ssam if (argc < 2) 112210294Ssam argc++, argv[1] = NULL; 112310294Ssam if (argc < 3) 112410294Ssam argc++, argv[2] = "-"; 112511756Ssam if (argc > 3) { 112611756Ssam printf("usage: %s remote-directory local-file\n", argv[0]); 112726049Sminshall code = -1; 112811756Ssam return; 112911756Ssam } 113036935Skarels cmd = argv[0][0] == 'n' ? "NLST" : "LIST"; 113126049Sminshall if (strcmp(argv[2], "-") && !globulize(&argv[2])) { 113226049Sminshall code = -1; 113311353Ssam return; 113426049Sminshall } 113532344Scsvsj if (strcmp(argv[2], "-") && *argv[2] != '|') 113632344Scsvsj if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) { 113732344Scsvsj code = -1; 113832344Scsvsj return; 113932344Scsvsj } 1140*37225Skarels recvrequest(cmd, argv[2], argv[1], "w", 0); 114110294Ssam } 114210294Ssam 114310294Ssam /* 114411756Ssam * Get a directory listing 114511756Ssam * of multiple remote files. 114611756Ssam */ 114711756Ssam mls(argc, argv) 114811756Ssam char *argv[]; 114911756Ssam { 115026049Sminshall char *cmd, mode[1], *dest; 115126049Sminshall int ointer, i, (*oldintr)(), mabort(); 115226049Sminshall extern jmp_buf jabort; 115311756Ssam 115413212Ssam if (argc < 2) { 115526497Sminshall (void) strcat(line, " "); 115613212Ssam printf("(remote-files) "); 115726497Sminshall (void) gets(&line[strlen(line)]); 115813212Ssam makeargv(); 115913212Ssam argc = margc; 116013212Ssam argv = margv; 116113212Ssam } 116213212Ssam if (argc < 3) { 116326497Sminshall (void) strcat(line, " "); 116413212Ssam printf("(local-file) "); 116526497Sminshall (void) gets(&line[strlen(line)]); 116613212Ssam makeargv(); 116713212Ssam argc = margc; 116813212Ssam argv = margv; 116913212Ssam } 117013212Ssam if (argc < 3) { 117126049Sminshall printf("usage:%s remote-files local-file\n", argv[0]); 117226049Sminshall code = -1; 117313212Ssam return; 117413212Ssam } 117513212Ssam dest = argv[argc - 1]; 117613212Ssam argv[argc - 1] = NULL; 117726049Sminshall if (strcmp(dest, "-") && *dest != '|') 117826049Sminshall if (!globulize(&dest) || !confirm("output to local-file:", dest)) { 117926049Sminshall code = -1; 118013212Ssam return; 118126049Sminshall } 118236940Skarels cmd = argv[0][1] == 'l' ? "NLST" : "LIST"; 118326049Sminshall mname = argv[0]; 118426049Sminshall mflag = 1; 118526049Sminshall oldintr = signal(SIGINT, mabort); 118626049Sminshall (void) setjmp(jabort); 118726049Sminshall for (i = 1; mflag && i < argc-1; ++i) { 118826049Sminshall *mode = (i == 1) ? 'w' : 'a'; 1189*37225Skarels recvrequest(cmd, dest, argv[i], mode, 0); 119026049Sminshall if (!mflag && fromatty) { 119126049Sminshall ointer = interactive; 119226049Sminshall interactive = 1; 119326049Sminshall if (confirm("Continue with", argv[0])) { 119426049Sminshall mflag ++; 119526049Sminshall } 119626049Sminshall interactive = ointer; 119726049Sminshall } 119826049Sminshall } 119926049Sminshall (void) signal(SIGINT, oldintr); 120026049Sminshall mflag = 0; 120111756Ssam } 120211756Ssam 120311756Ssam /* 120410294Ssam * Do a shell escape 120510294Ssam */ 120626497Sminshall /*ARGSUSED*/ 120710294Ssam shell(argc, argv) 120810294Ssam char *argv[]; 120910294Ssam { 121026497Sminshall int pid, (*old1)(), (*old2)(); 121126049Sminshall char shellnam[40], *shell, *namep; 121226497Sminshall union wait status; 121310294Ssam 121411756Ssam old1 = signal (SIGINT, SIG_IGN); 121511756Ssam old2 = signal (SIGQUIT, SIG_IGN); 121611756Ssam if ((pid = fork()) == 0) { 121711756Ssam for (pid = 3; pid < 20; pid++) 121826497Sminshall (void) close(pid); 121926497Sminshall (void) signal(SIGINT, SIG_DFL); 122026497Sminshall (void) signal(SIGQUIT, SIG_DFL); 122125908Smckusick shell = getenv("SHELL"); 122225908Smckusick if (shell == NULL) 122325908Smckusick shell = "/bin/sh"; 122425908Smckusick namep = rindex(shell,'/'); 122525908Smckusick if (namep == NULL) 122625908Smckusick namep = shell; 122726497Sminshall (void) strcpy(shellnam,"-"); 122826497Sminshall (void) strcat(shellnam, ++namep); 122926049Sminshall if (strcmp(namep, "sh") != 0) 123026049Sminshall shellnam[0] = '+'; 123126049Sminshall if (debug) { 123226049Sminshall printf ("%s\n", shell); 123326497Sminshall (void) fflush (stdout); 123411756Ssam } 123526049Sminshall if (argc > 1) { 123626049Sminshall execl(shell,shellnam,"-c",altarg,(char *)0); 123726049Sminshall } 123826049Sminshall else { 123926049Sminshall execl(shell,shellnam,(char *)0); 124026049Sminshall } 124125908Smckusick perror(shell); 124226049Sminshall code = -1; 124311756Ssam exit(1); 124426049Sminshall } 124511756Ssam if (pid > 0) 124611756Ssam while (wait(&status) != pid) 124711756Ssam ; 124826497Sminshall (void) signal(SIGINT, old1); 124926497Sminshall (void) signal(SIGQUIT, old2); 125026049Sminshall if (pid == -1) { 125111756Ssam perror("Try again later"); 125226049Sminshall code = -1; 125326049Sminshall } 125426049Sminshall else { 125526049Sminshall code = 0; 125626049Sminshall } 125711756Ssam return (0); 125810294Ssam } 125910294Ssam 126010294Ssam /* 126110294Ssam * Send new user information (re-login) 126210294Ssam */ 126310294Ssam user(argc, argv) 126410294Ssam int argc; 126510294Ssam char **argv; 126610294Ssam { 126735658Sbostic char acct[80], *getpass(); 126826049Sminshall int n, aflag = 0; 126910294Ssam 127010294Ssam if (argc < 2) { 127126497Sminshall (void) strcat(line, " "); 127210294Ssam printf("(username) "); 127326497Sminshall (void) gets(&line[strlen(line)]); 127410294Ssam makeargv(); 127510294Ssam argc = margc; 127610294Ssam argv = margv; 127710294Ssam } 127810294Ssam if (argc > 4) { 127910294Ssam printf("usage: %s username [password] [account]\n", argv[0]); 128026049Sminshall code = -1; 128111756Ssam return (0); 128210294Ssam } 128310294Ssam n = command("USER %s", argv[1]); 128410294Ssam if (n == CONTINUE) { 128510294Ssam if (argc < 3 ) 128635658Sbostic argv[2] = getpass("Password: "), argc++; 128710294Ssam n = command("PASS %s", argv[2]); 128810294Ssam } 128910294Ssam if (n == CONTINUE) { 129010294Ssam if (argc < 4) { 129110294Ssam printf("Account: "); (void) fflush(stdout); 129210294Ssam (void) fgets(acct, sizeof(acct) - 1, stdin); 129310294Ssam acct[strlen(acct) - 1] = '\0'; 129410294Ssam argv[3] = acct; argc++; 129510294Ssam } 129626049Sminshall n = command("ACCT %s", argv[3]); 129726049Sminshall aflag++; 129810294Ssam } 129910294Ssam if (n != COMPLETE) { 130026497Sminshall fprintf(stdout, "Login failed.\n"); 130110294Ssam return (0); 130210294Ssam } 130326049Sminshall if (!aflag && argc == 4) { 130426049Sminshall (void) command("ACCT %s", argv[3]); 130526049Sminshall } 130610294Ssam return (1); 130710294Ssam } 130810294Ssam 130910294Ssam /* 131010294Ssam * Print working directory. 131110294Ssam */ 131210294Ssam /*VARARGS*/ 131310294Ssam pwd() 131410294Ssam { 131537224Skarels int oldverbose = verbose; 131611756Ssam 131737224Skarels /* 131837224Skarels * If we aren't verbose, this doesn't do anything! 131937224Skarels */ 132037224Skarels verbose = 1; 132137224Skarels if (command("PWD") == ERROR && code == 500) { 132237224Skarels printf("PWD command not recognized, trying XPWD\n"); 132337224Skarels (void) command("XPWD"); 132437224Skarels } 132537224Skarels verbose = oldverbose; 132610294Ssam } 132710294Ssam 132810294Ssam /* 132910294Ssam * Make a directory. 133010294Ssam */ 133110294Ssam makedir(argc, argv) 133210294Ssam char *argv[]; 133310294Ssam { 133410294Ssam 133510294Ssam if (argc < 2) { 133626497Sminshall (void) strcat(line, " "); 133710294Ssam printf("(directory-name) "); 133826497Sminshall (void) gets(&line[strlen(line)]); 133910294Ssam makeargv(); 134010294Ssam argc = margc; 134110294Ssam argv = margv; 134210294Ssam } 134310294Ssam if (argc < 2) { 134426049Sminshall printf("usage: %s directory-name\n", argv[0]); 134526049Sminshall code = -1; 134610294Ssam return; 134710294Ssam } 134837224Skarels if (command("MKD %s", argv[1]) == ERROR && code == 500) { 134937224Skarels if (verbose) 135037224Skarels printf("MKD command not recognized, trying XMKD\n"); 135137224Skarels (void) command("XMKD %s", argv[1]); 135237224Skarels } 135310294Ssam } 135410294Ssam 135510294Ssam /* 135610294Ssam * Remove a directory. 135710294Ssam */ 135810294Ssam removedir(argc, argv) 135910294Ssam char *argv[]; 136010294Ssam { 136110294Ssam 136210294Ssam if (argc < 2) { 136326497Sminshall (void) strcat(line, " "); 136410294Ssam printf("(directory-name) "); 136526497Sminshall (void) gets(&line[strlen(line)]); 136610294Ssam makeargv(); 136710294Ssam argc = margc; 136810294Ssam argv = margv; 136910294Ssam } 137010294Ssam if (argc < 2) { 137126049Sminshall printf("usage: %s directory-name\n", argv[0]); 137226049Sminshall code = -1; 137310294Ssam return; 137410294Ssam } 137537224Skarels if (command("RMD %s", argv[1]) == ERROR && code == 500) { 137637224Skarels if (verbose) 137737224Skarels printf("RMD command not recognized, trying XRMD\n"); 137837224Skarels (void) command("XRMD %s", argv[1]); 137937224Skarels } 138010294Ssam } 138110294Ssam 138210294Ssam /* 138310294Ssam * Send a line, verbatim, to the remote machine. 138410294Ssam */ 138510294Ssam quote(argc, argv) 138610294Ssam char *argv[]; 138710294Ssam { 138810294Ssam int i; 138910294Ssam char buf[BUFSIZ]; 139010294Ssam 139110294Ssam if (argc < 2) { 139226497Sminshall (void) strcat(line, " "); 139310294Ssam printf("(command line to send) "); 139426497Sminshall (void) gets(&line[strlen(line)]); 139510294Ssam makeargv(); 139610294Ssam argc = margc; 139710294Ssam argv = margv; 139810294Ssam } 139910294Ssam if (argc < 2) { 140010294Ssam printf("usage: %s line-to-send\n", argv[0]); 140126049Sminshall code = -1; 140210294Ssam return; 140310294Ssam } 140426497Sminshall (void) strcpy(buf, argv[1]); 140510294Ssam for (i = 2; i < argc; i++) { 140626497Sminshall (void) strcat(buf, " "); 140726497Sminshall (void) strcat(buf, argv[i]); 140810294Ssam } 140926049Sminshall if (command(buf) == PRELIM) { 141026049Sminshall while (getreply(0) == PRELIM); 141126049Sminshall } 141210294Ssam } 141310294Ssam 141410294Ssam /* 141537224Skarels * Send a SITE command to the remote machine. The line 141637224Skarels * is sent almost verbatim to the remote machine, the 141737224Skarels * first argument is changed to SITE. 141837224Skarels */ 141937224Skarels 142037224Skarels site(argc, argv) 142137224Skarels char *argv[]; 142237224Skarels { 142337224Skarels int i; 142437224Skarels char buf[BUFSIZ]; 142537224Skarels 142637224Skarels if (argc < 2) { 142737224Skarels (void) strcat(line, " "); 142837224Skarels printf("(arguments to SITE command) "); 142937224Skarels (void) gets(&line[strlen(line)]); 143037224Skarels makeargv(); 143137224Skarels argc = margc; 143237224Skarels argv = margv; 143337224Skarels } 143437224Skarels if (argc < 2) { 143537224Skarels printf("usage: %s line-to-send\n", argv[0]); 143637224Skarels code = -1; 143737224Skarels return; 143837224Skarels } 143937224Skarels (void) strcpy(buf, "SITE "); 144037224Skarels (void) strcat(buf, argv[1]); 144137224Skarels for (i = 2; i < argc; i++) { 144237224Skarels (void) strcat(buf, " "); 144337224Skarels (void) strcat(buf, argv[i]); 144437224Skarels } 144537224Skarels if (command(buf) == PRELIM) { 144637224Skarels while (getreply(0) == PRELIM); 144737224Skarels } 144837224Skarels } 144937224Skarels 145037224Skarels do_chmod(argc, argv) 145137224Skarels char *argv[]; 145237224Skarels { 145337224Skarels if (argc == 2) { 145437224Skarels printf("usage: %s mode file-name\n", argv[0]); 145537224Skarels code = -1; 145637224Skarels return; 145737224Skarels } 145837224Skarels if (argc < 3) { 145937224Skarels (void) strcat(line, " "); 146037224Skarels printf("(mode and file-name) "); 146137224Skarels (void) gets(&line[strlen(line)]); 146237224Skarels makeargv(); 146337224Skarels argc = margc; 146437224Skarels argv = margv; 146537224Skarels } 146637224Skarels if (argc != 3) { 146737224Skarels printf("usage: %s mode file-name\n", argv[0]); 146837224Skarels code = -1; 146937224Skarels return; 147037224Skarels } 147137224Skarels (void)command("SITE CHMOD %s %s", argv[1], argv[2]); 147237224Skarels } 147337224Skarels 147437224Skarels do_umask(argc, argv) 147537224Skarels char *argv[]; 147637224Skarels { 147737224Skarels int oldverbose = verbose; 147837224Skarels 147937224Skarels verbose = 1; 148037224Skarels (void) command(argc == 1 ? "SITE UMASK" : "SITE UMASK %s", argv[1]); 148137224Skarels verbose = oldverbose; 148237224Skarels } 148337224Skarels 148437224Skarels idle(argc, argv) 148537224Skarels char *argv[]; 148637224Skarels { 148737224Skarels int oldverbose = verbose; 148837224Skarels 148937224Skarels verbose = 1; 149037224Skarels (void) command(argc == 1 ? "SITE IDLE" : "SITE IDLE %s", argv[1]); 149137224Skarels verbose = oldverbose; 149237224Skarels } 149337224Skarels 149437224Skarels /* 149510294Ssam * Ask the other side for help. 149610294Ssam */ 149710294Ssam rmthelp(argc, argv) 149810294Ssam char *argv[]; 149910294Ssam { 150010294Ssam int oldverbose = verbose; 150110294Ssam 150210294Ssam verbose = 1; 150310294Ssam (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]); 150410294Ssam verbose = oldverbose; 150510294Ssam } 150610294Ssam 150710294Ssam /* 150810294Ssam * Terminate session and exit. 150910294Ssam */ 151010294Ssam /*VARARGS*/ 151110294Ssam quit() 151210294Ssam { 151310294Ssam 151418286Sralph if (connected) 151518286Sralph disconnect(); 151626049Sminshall pswitch(1); 151726049Sminshall if (connected) { 151826049Sminshall disconnect(); 151926049Sminshall } 152010294Ssam exit(0); 152110294Ssam } 152210294Ssam 152310294Ssam /* 152410294Ssam * Terminate session, but don't exit. 152510294Ssam */ 152610294Ssam disconnect() 152710294Ssam { 152810294Ssam extern FILE *cout; 152910294Ssam extern int data; 153010294Ssam 153110294Ssam if (!connected) 153210294Ssam return; 153310294Ssam (void) command("QUIT"); 153426049Sminshall if (cout) { 153526049Sminshall (void) fclose(cout); 153626049Sminshall } 153710294Ssam cout = NULL; 153810294Ssam connected = 0; 153910294Ssam data = -1; 154026049Sminshall if (!proxy) { 154126049Sminshall macnum = 0; 154226049Sminshall } 154310294Ssam } 154411353Ssam 154511650Ssam confirm(cmd, file) 154611353Ssam char *cmd, *file; 154711353Ssam { 154811353Ssam char line[BUFSIZ]; 154911353Ssam 155011353Ssam if (!interactive) 155111650Ssam return (1); 155211353Ssam printf("%s %s? ", cmd, file); 155326497Sminshall (void) fflush(stdout); 155426497Sminshall (void) gets(line); 155511650Ssam return (*line != 'n' && *line != 'N'); 155611353Ssam } 155711353Ssam 155811353Ssam fatal(msg) 155911353Ssam char *msg; 156011353Ssam { 156111353Ssam 156226497Sminshall fprintf(stderr, "ftp: %s\n", msg); 156311353Ssam exit(1); 156411353Ssam } 156511353Ssam 156611353Ssam /* 156711353Ssam * Glob a local file name specification with 156811353Ssam * the expectation of a single return value. 156911353Ssam * Can't control multiple values being expanded 157011353Ssam * from the expression, we return only the first. 157111353Ssam */ 157211353Ssam globulize(cpp) 157311353Ssam char **cpp; 157411353Ssam { 157511353Ssam char **globbed; 157611353Ssam 157711353Ssam if (!doglob) 157811353Ssam return (1); 157911353Ssam globbed = glob(*cpp); 158011353Ssam if (globerr != NULL) { 158111353Ssam printf("%s: %s\n", *cpp, globerr); 158236421Sbostic if (globbed) { 158311353Ssam blkfree(globbed); 158436421Sbostic free(globbed); 158536421Sbostic } 158611353Ssam return (0); 158711353Ssam } 158811353Ssam if (globbed) { 158911353Ssam *cpp = *globbed++; 159011353Ssam /* don't waste too much memory */ 159136421Sbostic if (*globbed) { 159211353Ssam blkfree(globbed); 159336421Sbostic free(globbed); 159436421Sbostic } 159511353Ssam } 159611353Ssam return (1); 159711353Ssam } 159826049Sminshall 159926049Sminshall account(argc,argv) 160026049Sminshall int argc; 160126049Sminshall char **argv; 160226049Sminshall { 160335658Sbostic char acct[50], *getpass(), *ap; 160426049Sminshall 160526049Sminshall if (argc > 1) { 160626049Sminshall ++argv; 160726049Sminshall --argc; 160826049Sminshall (void) strncpy(acct,*argv,49); 160936268Sbostic acct[49] = '\0'; 161026049Sminshall while (argc > 1) { 161126049Sminshall --argc; 161226049Sminshall ++argv; 161326049Sminshall (void) strncat(acct,*argv, 49-strlen(acct)); 161426049Sminshall } 161526049Sminshall ap = acct; 161626049Sminshall } 161726049Sminshall else { 161835658Sbostic ap = getpass("Account:"); 161926049Sminshall } 162026049Sminshall (void) command("ACCT %s", ap); 162126049Sminshall } 162226049Sminshall 162326049Sminshall jmp_buf abortprox; 162426049Sminshall 162526049Sminshall proxabort() 162626049Sminshall { 162726049Sminshall extern int proxy; 162826049Sminshall 162926049Sminshall if (!proxy) { 163026049Sminshall pswitch(1); 163126049Sminshall } 163226049Sminshall if (connected) { 163326049Sminshall proxflag = 1; 163426049Sminshall } 163526049Sminshall else { 163626049Sminshall proxflag = 0; 163726049Sminshall } 163826049Sminshall pswitch(0); 163926049Sminshall longjmp(abortprox,1); 164026049Sminshall } 164126049Sminshall 164226049Sminshall doproxy(argc,argv) 164326049Sminshall int argc; 164426049Sminshall char *argv[]; 164526049Sminshall { 164626049Sminshall int (*oldintr)(), proxabort(); 164726049Sminshall register struct cmd *c; 164826049Sminshall struct cmd *getcmd(); 164926049Sminshall extern struct cmd cmdtab[]; 165026049Sminshall extern jmp_buf abortprox; 165126049Sminshall 165226049Sminshall if (argc < 2) { 165326497Sminshall (void) strcat(line, " "); 165426049Sminshall printf("(command) "); 165526497Sminshall (void) gets(&line[strlen(line)]); 165626049Sminshall makeargv(); 165726049Sminshall argc = margc; 165826049Sminshall argv = margv; 165926049Sminshall } 166026049Sminshall if (argc < 2) { 166126049Sminshall printf("usage:%s command\n", argv[0]); 166226049Sminshall code = -1; 166326049Sminshall return; 166426049Sminshall } 166526049Sminshall c = getcmd(argv[1]); 166626049Sminshall if (c == (struct cmd *) -1) { 166726049Sminshall printf("?Ambiguous command\n"); 166826497Sminshall (void) fflush(stdout); 166926049Sminshall code = -1; 167026049Sminshall return; 167126049Sminshall } 167226049Sminshall if (c == 0) { 167326049Sminshall printf("?Invalid command\n"); 167426497Sminshall (void) fflush(stdout); 167526049Sminshall code = -1; 167626049Sminshall return; 167726049Sminshall } 167826049Sminshall if (!c->c_proxy) { 167926049Sminshall printf("?Invalid proxy command\n"); 168026497Sminshall (void) fflush(stdout); 168126049Sminshall code = -1; 168226049Sminshall return; 168326049Sminshall } 168426049Sminshall if (setjmp(abortprox)) { 168526049Sminshall code = -1; 168626049Sminshall return; 168726049Sminshall } 168826049Sminshall oldintr = signal(SIGINT, proxabort); 168926049Sminshall pswitch(1); 169026049Sminshall if (c->c_conn && !connected) { 169126049Sminshall printf("Not connected\n"); 169226497Sminshall (void) fflush(stdout); 169326049Sminshall pswitch(0); 169426049Sminshall (void) signal(SIGINT, oldintr); 169526049Sminshall code = -1; 169626049Sminshall return; 169726049Sminshall } 169826049Sminshall (*c->c_handler)(argc-1, argv+1); 169926049Sminshall if (connected) { 170026049Sminshall proxflag = 1; 170126049Sminshall } 170226049Sminshall else { 170326049Sminshall proxflag = 0; 170426049Sminshall } 170526049Sminshall pswitch(0); 170626049Sminshall (void) signal(SIGINT, oldintr); 170726049Sminshall } 170826049Sminshall 170926049Sminshall setcase() 171026049Sminshall { 171126049Sminshall mcase = !mcase; 171226049Sminshall printf("Case mapping %s.\n", onoff(mcase)); 171326049Sminshall code = mcase; 171426049Sminshall } 171526049Sminshall 171626049Sminshall setcr() 171726049Sminshall { 171826049Sminshall crflag = !crflag; 171926049Sminshall printf("Carriage Return stripping %s.\n", onoff(crflag)); 172026049Sminshall code = crflag; 172126049Sminshall } 172226049Sminshall 172326049Sminshall setntrans(argc,argv) 172426049Sminshall int argc; 172526049Sminshall char *argv[]; 172626049Sminshall { 172726049Sminshall if (argc == 1) { 172826049Sminshall ntflag = 0; 172926049Sminshall printf("Ntrans off.\n"); 173026049Sminshall code = ntflag; 173126049Sminshall return; 173226049Sminshall } 173326049Sminshall ntflag++; 173426049Sminshall code = ntflag; 173526049Sminshall (void) strncpy(ntin, argv[1], 16); 173626049Sminshall ntin[16] = '\0'; 173726049Sminshall if (argc == 2) { 173826049Sminshall ntout[0] = '\0'; 173926049Sminshall return; 174026049Sminshall } 174126049Sminshall (void) strncpy(ntout, argv[2], 16); 174226049Sminshall ntout[16] = '\0'; 174326049Sminshall } 174426049Sminshall 174526049Sminshall char * 174626049Sminshall dotrans(name) 174726049Sminshall char *name; 174826049Sminshall { 174926049Sminshall static char new[MAXPATHLEN]; 175026049Sminshall char *cp1, *cp2 = new; 175126049Sminshall register int i, ostop, found; 175226049Sminshall 175326049Sminshall for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++); 175426049Sminshall for (cp1 = name; *cp1; cp1++) { 175526049Sminshall found = 0; 175626049Sminshall for (i = 0; *(ntin + i) && i < 16; i++) { 175726049Sminshall if (*cp1 == *(ntin + i)) { 175826049Sminshall found++; 175926049Sminshall if (i < ostop) { 176026049Sminshall *cp2++ = *(ntout + i); 176126049Sminshall } 176226049Sminshall break; 176326049Sminshall } 176426049Sminshall } 176526049Sminshall if (!found) { 176626049Sminshall *cp2++ = *cp1; 176726049Sminshall } 176826049Sminshall } 176926049Sminshall *cp2 = '\0'; 177026049Sminshall return(new); 177126049Sminshall } 177226049Sminshall 177326049Sminshall setnmap(argc, argv) 177426049Sminshall int argc; 177526049Sminshall char *argv[]; 177626049Sminshall { 177726049Sminshall char *cp; 177826049Sminshall 177926049Sminshall if (argc == 1) { 178026049Sminshall mapflag = 0; 178126049Sminshall printf("Nmap off.\n"); 178226049Sminshall code = mapflag; 178326049Sminshall return; 178426049Sminshall } 178526049Sminshall if (argc < 3) { 178626497Sminshall (void) strcat(line, " "); 178726049Sminshall printf("(mapout) "); 178826497Sminshall (void) gets(&line[strlen(line)]); 178926049Sminshall makeargv(); 179026049Sminshall argc = margc; 179126049Sminshall argv = margv; 179226049Sminshall } 179326049Sminshall if (argc < 3) { 179426049Sminshall printf("Usage: %s [mapin mapout]\n",argv[0]); 179526049Sminshall code = -1; 179626049Sminshall return; 179726049Sminshall } 179826049Sminshall mapflag = 1; 179926049Sminshall code = 1; 180026049Sminshall cp = index(altarg, ' '); 180126049Sminshall if (proxy) { 180226049Sminshall while(*++cp == ' '); 180326049Sminshall altarg = cp; 180426049Sminshall cp = index(altarg, ' '); 180526049Sminshall } 180626049Sminshall *cp = '\0'; 180726049Sminshall (void) strncpy(mapin, altarg, MAXPATHLEN - 1); 180826049Sminshall while (*++cp == ' '); 180926049Sminshall (void) strncpy(mapout, cp, MAXPATHLEN - 1); 181026049Sminshall } 181126049Sminshall 181226049Sminshall char * 181326049Sminshall domap(name) 181426049Sminshall char *name; 181526049Sminshall { 181626049Sminshall static char new[MAXPATHLEN]; 181726049Sminshall register char *cp1 = name, *cp2 = mapin; 181826049Sminshall char *tp[9], *te[9]; 181936689Scsvsj int i, toks[9], toknum = 0, match = 1; 182026049Sminshall 182126049Sminshall for (i=0; i < 9; ++i) { 182226049Sminshall toks[i] = 0; 182326049Sminshall } 182426049Sminshall while (match && *cp1 && *cp2) { 182526049Sminshall switch (*cp2) { 182626049Sminshall case '\\': 182726049Sminshall if (*++cp2 != *cp1) { 182826049Sminshall match = 0; 182926049Sminshall } 183026049Sminshall break; 183126049Sminshall case '$': 183226049Sminshall if (*(cp2+1) >= '1' && (*cp2+1) <= '9') { 183326049Sminshall if (*cp1 != *(++cp2+1)) { 183426049Sminshall toks[toknum = *cp2 - '1']++; 183526049Sminshall tp[toknum] = cp1; 183626049Sminshall while (*++cp1 && *(cp2+1) 183726049Sminshall != *cp1); 183826049Sminshall te[toknum] = cp1; 183926049Sminshall } 184026049Sminshall cp2++; 184126049Sminshall break; 184226049Sminshall } 184336935Skarels /* FALLTHROUGH */ 184426049Sminshall default: 184526049Sminshall if (*cp2 != *cp1) { 184626049Sminshall match = 0; 184726049Sminshall } 184826049Sminshall break; 184926049Sminshall } 185036689Scsvsj if (match && *cp1) { 185126049Sminshall cp1++; 185226049Sminshall } 185336689Scsvsj if (match && *cp2) { 185426049Sminshall cp2++; 185526049Sminshall } 185626049Sminshall } 185736689Scsvsj if (!match && *cp1) /* last token mismatch */ 185836689Scsvsj { 185936689Scsvsj toks[toknum] = 0; 186036689Scsvsj } 186126049Sminshall cp1 = new; 186226049Sminshall *cp1 = '\0'; 186326049Sminshall cp2 = mapout; 186426049Sminshall while (*cp2) { 186526049Sminshall match = 0; 186626049Sminshall switch (*cp2) { 186726049Sminshall case '\\': 186826049Sminshall if (*(cp2 + 1)) { 186926049Sminshall *cp1++ = *++cp2; 187026049Sminshall } 187126049Sminshall break; 187226049Sminshall case '[': 187326049Sminshall LOOP: 187426049Sminshall if (*++cp2 == '$' && isdigit(*(cp2+1))) { 187526049Sminshall if (*++cp2 == '0') { 187626049Sminshall char *cp3 = name; 187726049Sminshall 187826049Sminshall while (*cp3) { 187926049Sminshall *cp1++ = *cp3++; 188026049Sminshall } 188126049Sminshall match = 1; 188226049Sminshall } 188326049Sminshall else if (toks[toknum = *cp2 - '1']) { 188426049Sminshall char *cp3 = tp[toknum]; 188526049Sminshall 188626049Sminshall while (cp3 != te[toknum]) { 188726049Sminshall *cp1++ = *cp3++; 188826049Sminshall } 188926049Sminshall match = 1; 189026049Sminshall } 189126049Sminshall } 189226049Sminshall else { 189326049Sminshall while (*cp2 && *cp2 != ',' && 189426049Sminshall *cp2 != ']') { 189526049Sminshall if (*cp2 == '\\') { 189626049Sminshall cp2++; 189726049Sminshall } 189826049Sminshall else if (*cp2 == '$' && 189926049Sminshall isdigit(*(cp2+1))) { 190026049Sminshall if (*++cp2 == '0') { 190126049Sminshall char *cp3 = name; 190226049Sminshall 190326049Sminshall while (*cp3) { 190426049Sminshall *cp1++ = *cp3++; 190526049Sminshall } 190626049Sminshall } 190726049Sminshall else if (toks[toknum = 190826049Sminshall *cp2 - '1']) { 190926049Sminshall char *cp3=tp[toknum]; 191026049Sminshall 191126049Sminshall while (cp3 != 191226049Sminshall te[toknum]) { 191326049Sminshall *cp1++ = *cp3++; 191426049Sminshall } 191526049Sminshall } 191626049Sminshall } 191726049Sminshall else if (*cp2) { 191826049Sminshall *cp1++ = *cp2++; 191926049Sminshall } 192026049Sminshall } 192126049Sminshall if (!*cp2) { 192226049Sminshall printf("nmap: unbalanced brackets\n"); 192326049Sminshall return(name); 192426049Sminshall } 192526049Sminshall match = 1; 192626049Sminshall cp2--; 192726049Sminshall } 192826049Sminshall if (match) { 192926049Sminshall while (*++cp2 && *cp2 != ']') { 193026049Sminshall if (*cp2 == '\\' && *(cp2 + 1)) { 193126049Sminshall cp2++; 193226049Sminshall } 193326049Sminshall } 193426049Sminshall if (!*cp2) { 193526049Sminshall printf("nmap: unbalanced brackets\n"); 193626049Sminshall return(name); 193726049Sminshall } 193826049Sminshall break; 193926049Sminshall } 194026049Sminshall switch (*++cp2) { 194126049Sminshall case ',': 194226049Sminshall goto LOOP; 194326049Sminshall case ']': 194426049Sminshall break; 194526049Sminshall default: 194626049Sminshall cp2--; 194726049Sminshall goto LOOP; 194826049Sminshall } 194926049Sminshall break; 195026049Sminshall case '$': 195126049Sminshall if (isdigit(*(cp2 + 1))) { 195226049Sminshall if (*++cp2 == '0') { 195326049Sminshall char *cp3 = name; 195426049Sminshall 195526049Sminshall while (*cp3) { 195626049Sminshall *cp1++ = *cp3++; 195726049Sminshall } 195826049Sminshall } 195926049Sminshall else if (toks[toknum = *cp2 - '1']) { 196026049Sminshall char *cp3 = tp[toknum]; 196126049Sminshall 196226049Sminshall while (cp3 != te[toknum]) { 196326049Sminshall *cp1++ = *cp3++; 196426049Sminshall } 196526049Sminshall } 196626049Sminshall break; 196726049Sminshall } 196826049Sminshall /* intentional drop through */ 196926049Sminshall default: 197026049Sminshall *cp1++ = *cp2; 197126049Sminshall break; 197226049Sminshall } 197326049Sminshall cp2++; 197426049Sminshall } 197526049Sminshall *cp1 = '\0'; 197626049Sminshall if (!*new) { 197726049Sminshall return(name); 197826049Sminshall } 197926049Sminshall return(new); 198026049Sminshall } 198126049Sminshall 198226049Sminshall setsunique() 198326049Sminshall { 198426049Sminshall sunique = !sunique; 198526049Sminshall printf("Store unique %s.\n", onoff(sunique)); 198626049Sminshall code = sunique; 198726049Sminshall } 198826049Sminshall 198926049Sminshall setrunique() 199026049Sminshall { 199126049Sminshall runique = !runique; 199226049Sminshall printf("Receive unique %s.\n", onoff(runique)); 199326049Sminshall code = runique; 199426049Sminshall } 199526049Sminshall 199626049Sminshall /* change directory to perent directory */ 199726049Sminshall cdup() 199826049Sminshall { 199937224Skarels if (command("CDUP") == ERROR && code == 500) { 200037224Skarels if (verbose) 200137224Skarels printf("CDUP command not recognized, trying XCUP\n"); 200237224Skarels (void) command("XCUP"); 200337224Skarels } 200426049Sminshall } 200526049Sminshall 200637224Skarels /* restart transfer at specific point */ 200737224Skarels restart(argc, argv) 200837224Skarels int argc; 200937224Skarels char *argv[]; 201037224Skarels { 201137224Skarels extern long atol(); 201237224Skarels if (argc != 2) 201337224Skarels printf("restart: offset not specified\n"); 201437224Skarels else { 201537224Skarels restart_point = atol(argv[1]); 201637224Skarels printf("restarting at %ld. %s\n", restart_point, 201737224Skarels "execute get, put or append to initiate transfer"); 201837224Skarels } 201937224Skarels } 202036935Skarels 202136935Skarels /* show remote system type */ 202236935Skarels syst() 202336935Skarels { 202436935Skarels (void) command("SYST"); 202536935Skarels } 202636935Skarels 202726049Sminshall macdef(argc, argv) 202826049Sminshall int argc; 202926049Sminshall char *argv[]; 203026049Sminshall { 203126049Sminshall char *tmp; 203226049Sminshall int c; 203326049Sminshall 203426049Sminshall if (macnum == 16) { 203526049Sminshall printf("Limit of 16 macros have already been defined\n"); 203626049Sminshall code = -1; 203726049Sminshall return; 203826049Sminshall } 203926049Sminshall if (argc < 2) { 204026497Sminshall (void) strcat(line, " "); 204126049Sminshall printf("(macro name) "); 204226497Sminshall (void) gets(&line[strlen(line)]); 204326049Sminshall makeargv(); 204426049Sminshall argc = margc; 204526049Sminshall argv = margv; 204626049Sminshall } 204726049Sminshall if (argc != 2) { 204826049Sminshall printf("Usage: %s macro_name\n",argv[0]); 204926049Sminshall code = -1; 205026049Sminshall return; 205126049Sminshall } 205226049Sminshall if (interactive) { 205326049Sminshall printf("Enter macro line by line, terminating it with a null line\n"); 205426049Sminshall } 205526497Sminshall (void) strncpy(macros[macnum].mac_name, argv[1], 8); 205626049Sminshall if (macnum == 0) { 205726049Sminshall macros[macnum].mac_start = macbuf; 205826049Sminshall } 205926049Sminshall else { 206026049Sminshall macros[macnum].mac_start = macros[macnum - 1].mac_end + 1; 206126049Sminshall } 206226049Sminshall tmp = macros[macnum].mac_start; 206326049Sminshall while (tmp != macbuf+4096) { 206426049Sminshall if ((c = getchar()) == EOF) { 206526049Sminshall printf("macdef:end of file encountered\n"); 206626049Sminshall code = -1; 206726049Sminshall return; 206826049Sminshall } 206926049Sminshall if ((*tmp = c) == '\n') { 207026049Sminshall if (tmp == macros[macnum].mac_start) { 207126049Sminshall macros[macnum++].mac_end = tmp; 207226049Sminshall code = 0; 207326049Sminshall return; 207426049Sminshall } 207526049Sminshall if (*(tmp-1) == '\0') { 207626049Sminshall macros[macnum++].mac_end = tmp - 1; 207726049Sminshall code = 0; 207826049Sminshall return; 207926049Sminshall } 208026049Sminshall *tmp = '\0'; 208126049Sminshall } 208226049Sminshall tmp++; 208326049Sminshall } 208426049Sminshall while (1) { 208536935Skarels while ((c = getchar()) != '\n' && c != EOF) 208636935Skarels /* LOOP */; 208726049Sminshall if (c == EOF || getchar() == '\n') { 208826049Sminshall printf("Macro not defined - 4k buffer exceeded\n"); 208926049Sminshall code = -1; 209026049Sminshall return; 209126049Sminshall } 209226049Sminshall } 209326049Sminshall } 209436935Skarels 209536935Skarels /* 209636935Skarels * get size of file on remote machine 209736935Skarels */ 209836935Skarels sizecmd(argc, argv) 209936935Skarels char *argv[]; 210036935Skarels { 210136935Skarels 210236935Skarels if (argc < 2) { 210336935Skarels (void) strcat(line, " "); 210436935Skarels printf("(filename) "); 210536935Skarels (void) gets(&line[strlen(line)]); 210636935Skarels makeargv(); 210736935Skarels argc = margc; 210836935Skarels argv = margv; 210936935Skarels } 211036935Skarels if (argc < 2) { 211136935Skarels printf("usage:%s filename\n", argv[0]); 211236935Skarels code = -1; 211336935Skarels return; 211436935Skarels } 211536935Skarels (void) command("SIZE %s", argv[1]); 211636935Skarels } 211736935Skarels 211836935Skarels /* 211936935Skarels * get last modification time of file on remote machine 212036935Skarels */ 212136935Skarels modtime(argc, argv) 212236935Skarels char *argv[]; 212336935Skarels { 212436935Skarels int overbose; 212536935Skarels 212636935Skarels if (argc < 2) { 212736935Skarels (void) strcat(line, " "); 212836935Skarels printf("(filename) "); 212936935Skarels (void) gets(&line[strlen(line)]); 213036935Skarels makeargv(); 213136935Skarels argc = margc; 213236935Skarels argv = margv; 213336935Skarels } 213436935Skarels if (argc < 2) { 213536935Skarels printf("usage:%s filename\n", argv[0]); 213636935Skarels code = -1; 213736935Skarels return; 213836935Skarels } 213936940Skarels overbose = verbose; 214036940Skarels if (debug == 0) 214136940Skarels verbose = -1; 214236935Skarels if (command("MDTM %s", argv[1]) == COMPLETE) { 214336935Skarels int yy, mo, day, hour, min, sec; 214436935Skarels sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo, 214536935Skarels &day, &hour, &min, &sec); 214636935Skarels /* might want to print this in local time */ 214736935Skarels printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1], 214836935Skarels mo, day, yy, hour, min, sec); 214936935Skarels } else 215036935Skarels fputs(reply_string, stdout); 215136935Skarels verbose = overbose; 215236935Skarels } 215336935Skarels 215436935Skarels /* 215537224Skarels * show status on reomte machine 215636935Skarels */ 215736935Skarels rmtstatus(argc, argv) 215836935Skarels char *argv[]; 215936935Skarels { 216036935Skarels (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]); 216136935Skarels } 216237224Skarels 216337224Skarels /* 216437224Skarels * get file if modtime is more recent than current file 216537224Skarels */ 216637224Skarels newer(argc, argv) 216737224Skarels char *argv[]; 216837224Skarels { 216937224Skarels if (getit(argc, argv, -1, "w")) 217037224Skarels printf("Local file \"%s\" is newer than remote file \"%s\"\n", 217137224Skarels argv[1], argv[2]); 217237224Skarels } 2173