121737Sdist /* 226049Sminshall * Copyright (c) 1985 Regents of the University of California. 321737Sdist * All rights reserved. The Berkeley software License Agreement 421737Sdist * specifies the terms and conditions for redistribution. 521737Sdist */ 621737Sdist 710294Ssam #ifndef lint 8*26497Sminshall static char sccsid[] = "@(#)cmds.c 5.5 (Berkeley) 03/07/86"; 921737Sdist #endif not lint 1010294Ssam 1110294Ssam /* 1210294Ssam * FTP User Program -- Command Routines. 1310294Ssam */ 1426049Sminshall #include "ftp_var.h" 1510294Ssam #include <sys/socket.h> 1610294Ssam 1712396Ssam #include <arpa/ftp.h> 1812396Ssam 1910294Ssam #include <signal.h> 2010294Ssam #include <stdio.h> 2110294Ssam #include <errno.h> 2210294Ssam #include <netdb.h> 2326049Sminshall #include <ctype.h> 24*26497Sminshall #include <sys/wait.h> 2510294Ssam 2610294Ssam 2711353Ssam extern char *globerr; 2811353Ssam extern char **glob(); 2911756Ssam extern char *home; 3011353Ssam extern short gflag; 3111756Ssam extern char *remglob(); 3211756Ssam extern char *getenv(); 3311756Ssam extern char *index(); 3411756Ssam extern char *rindex(); 3526049Sminshall char *mname; 3626049Sminshall jmp_buf jabort; 3726049Sminshall char *dotrans(), *domap(); 3810294Ssam 3910294Ssam /* 4010294Ssam * Connect to peer server and 4110294Ssam * auto-login, if possible. 4210294Ssam */ 4310294Ssam setpeer(argc, argv) 4410294Ssam int argc; 4510294Ssam char *argv[]; 4610294Ssam { 4725903Skarels char *host, *hookup(); 4810294Ssam int port; 4910294Ssam 5010294Ssam if (connected) { 5126049Sminshall printf("Already connected to %s, use close first.\n", 5210294Ssam hostname); 5326049Sminshall code = -1; 5410294Ssam return; 5510294Ssam } 5610294Ssam if (argc < 2) { 57*26497Sminshall (void) strcat(line, " "); 5810294Ssam printf("(to) "); 59*26497Sminshall (void) gets(&line[strlen(line)]); 6010294Ssam makeargv(); 6110294Ssam argc = margc; 6210294Ssam argv = margv; 6310294Ssam } 6410294Ssam if (argc > 3) { 6510294Ssam printf("usage: %s host-name [port]\n", argv[0]); 6626049Sminshall code = -1; 6710294Ssam return; 6810294Ssam } 6910294Ssam port = sp->s_port; 7010294Ssam if (argc > 2) { 7111218Ssam port = atoi(argv[2]); 7210294Ssam if (port <= 0) { 7311218Ssam printf("%s: bad port number-- %s\n", argv[1], argv[2]); 7411218Ssam printf ("usage: %s host-name [port]\n", argv[0]); 7526049Sminshall code = -1; 7610294Ssam return; 7710294Ssam } 7810294Ssam port = htons(port); 7910294Ssam } 8010294Ssam host = hookup(argv[1], port); 8110294Ssam if (host) { 8210294Ssam connected = 1; 8310294Ssam if (autologin) 84*26497Sminshall (void) login(argv[1]); 8510294Ssam } 8610294Ssam } 8710294Ssam 8810294Ssam struct types { 8910294Ssam char *t_name; 9010294Ssam char *t_mode; 9110294Ssam int t_type; 9211218Ssam char *t_arg; 9310294Ssam } types[] = { 9411218Ssam { "ascii", "A", TYPE_A, 0 }, 9511218Ssam { "binary", "I", TYPE_I, 0 }, 9611218Ssam { "image", "I", TYPE_I, 0 }, 9711218Ssam { "ebcdic", "E", TYPE_E, 0 }, 9811218Ssam { "tenex", "L", TYPE_L, bytename }, 9910294Ssam 0 10010294Ssam }; 10110294Ssam 10210294Ssam /* 10310294Ssam * Set transfer type. 10410294Ssam */ 10510294Ssam settype(argc, argv) 10610294Ssam char *argv[]; 10710294Ssam { 10810294Ssam register struct types *p; 10911218Ssam int comret; 11010294Ssam 11110294Ssam if (argc > 2) { 11210294Ssam char *sep; 11310294Ssam 11410294Ssam printf("usage: %s [", argv[0]); 11510294Ssam sep = " "; 11610294Ssam for (p = types; p->t_name; p++) { 11710294Ssam printf("%s%s", sep, p->t_name); 11810294Ssam if (*sep == ' ') 11910294Ssam sep = " | "; 12010294Ssam } 12110294Ssam printf(" ]\n"); 12226049Sminshall code = -1; 12310294Ssam return; 12410294Ssam } 12510294Ssam if (argc < 2) { 12610294Ssam printf("Using %s mode to transfer files.\n", typename); 12726049Sminshall code = 0; 12810294Ssam return; 12910294Ssam } 13010294Ssam for (p = types; p->t_name; p++) 13110294Ssam if (strcmp(argv[1], p->t_name) == 0) 13210294Ssam break; 13310294Ssam if (p->t_name == 0) { 13410294Ssam printf("%s: unknown mode\n", argv[1]); 13526049Sminshall code = -1; 13610294Ssam return; 13710294Ssam } 13811218Ssam if ((p->t_arg != NULL) && (*(p->t_arg) != '\0')) 13911218Ssam comret = command ("TYPE %s %s", p->t_mode, p->t_arg); 14011218Ssam else 14111218Ssam comret = command("TYPE %s", p->t_mode); 14211218Ssam if (comret == COMPLETE) { 143*26497Sminshall (void) strcpy(typename, p->t_name); 14410294Ssam type = p->t_type; 14510294Ssam } 14610294Ssam } 14710294Ssam 14810294Ssam /* 14910294Ssam * Set binary transfer type. 15010294Ssam */ 15110294Ssam /*VARARGS*/ 15210294Ssam setbinary() 15310294Ssam { 15410294Ssam 15510294Ssam call(settype, "type", "binary", 0); 15610294Ssam } 15710294Ssam 15810294Ssam /* 15910294Ssam * Set ascii transfer type. 16010294Ssam */ 16110294Ssam /*VARARGS*/ 16210294Ssam setascii() 16310294Ssam { 16410294Ssam 16510294Ssam call(settype, "type", "ascii", 0); 16610294Ssam } 16710294Ssam 16810294Ssam /* 16910294Ssam * Set tenex transfer type. 17010294Ssam */ 17110294Ssam /*VARARGS*/ 17210294Ssam settenex() 17310294Ssam { 17410294Ssam 17510294Ssam call(settype, "type", "tenex", 0); 17610294Ssam } 17710294Ssam 17810294Ssam /* 17910294Ssam * Set ebcdic transfer type. 18010294Ssam */ 18110294Ssam /*VARARGS*/ 18210294Ssam setebcdic() 18310294Ssam { 18410294Ssam 18510294Ssam call(settype, "type", "ebcdic", 0); 18610294Ssam } 18710294Ssam 18810294Ssam /* 18910294Ssam * Set file transfer mode. 19010294Ssam */ 191*26497Sminshall /*ARGSUSED*/ 19210294Ssam setmode(argc, argv) 19310294Ssam char *argv[]; 19410294Ssam { 19510294Ssam 19610294Ssam printf("We only support %s mode, sorry.\n", modename); 19726049Sminshall code = -1; 19810294Ssam } 19910294Ssam 20010294Ssam /* 20110294Ssam * Set file transfer format. 20210294Ssam */ 203*26497Sminshall /*ARGSUSED*/ 20410294Ssam setform(argc, argv) 20510294Ssam char *argv[]; 20610294Ssam { 20710294Ssam 20810294Ssam printf("We only support %s format, sorry.\n", formname); 20926049Sminshall code = -1; 21010294Ssam } 21110294Ssam 21210294Ssam /* 21310294Ssam * Set file transfer structure. 21410294Ssam */ 215*26497Sminshall /*ARGSUSED*/ 21610294Ssam setstruct(argc, argv) 21710294Ssam char *argv[]; 21810294Ssam { 21910294Ssam 22010294Ssam printf("We only support %s structure, sorry.\n", structname); 22126049Sminshall code = -1; 22210294Ssam } 22310294Ssam 22418286Sralph /* 22518286Sralph * Send a single file. 22618286Sralph */ 22710294Ssam put(argc, argv) 22811756Ssam int argc; 22910294Ssam char *argv[]; 23010294Ssam { 23111650Ssam char *cmd; 23226049Sminshall int loc = 0; 23325908Smckusick char *oldargv1; 23411650Ssam 23526049Sminshall if (argc == 2) { 23626049Sminshall argc++; 23726049Sminshall argv[2] = argv[1]; 23826049Sminshall loc++; 23926049Sminshall } 24010294Ssam if (argc < 2) { 241*26497Sminshall (void) strcat(line, " "); 24210294Ssam printf("(local-file) "); 243*26497Sminshall (void) gets(&line[strlen(line)]); 24410294Ssam makeargv(); 24510294Ssam argc = margc; 24610294Ssam argv = margv; 24710294Ssam } 24810294Ssam if (argc < 2) { 24910294Ssam usage: 25026049Sminshall printf("usage:%s local-file remote-file\n", argv[0]); 25126049Sminshall code = -1; 25210294Ssam return; 25310294Ssam } 25410294Ssam if (argc < 3) { 255*26497Sminshall (void) strcat(line, " "); 25610294Ssam printf("(remote-file) "); 257*26497Sminshall (void) gets(&line[strlen(line)]); 25810294Ssam makeargv(); 25910294Ssam argc = margc; 26010294Ssam argv = margv; 26110294Ssam } 26210294Ssam if (argc < 3) 26310294Ssam goto usage; 26425908Smckusick oldargv1 = argv[1]; 26526049Sminshall if (!globulize(&argv[1])) { 26626049Sminshall code = -1; 26711353Ssam return; 26826049Sminshall } 26925908Smckusick /* 27025908Smckusick * If "globulize" modifies argv[1], and argv[2] is a copy of 27125908Smckusick * the old argv[1], make it a copy of the new argv[1]. 27225908Smckusick */ 27326049Sminshall if (argv[1] != oldargv1 && argv[2] == oldargv1) { 27425908Smckusick argv[2] = argv[1]; 27526049Sminshall } 27626049Sminshall cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR"); 27726049Sminshall if (loc && ntflag) { 27826049Sminshall argv[2] = dotrans(argv[2]); 27926049Sminshall } 28026049Sminshall if (loc && mapflag) { 28126049Sminshall argv[2] = domap(argv[2]); 28226049Sminshall } 28311650Ssam sendrequest(cmd, argv[1], argv[2]); 28410294Ssam } 28510294Ssam 28610294Ssam /* 28711756Ssam * Send multiple files. 28810294Ssam */ 28911353Ssam mput(argc, argv) 29011353Ssam char *argv[]; 29111353Ssam { 29213212Ssam register int i; 29326049Sminshall int ointer, (*oldintr)(), mabort(); 29426049Sminshall extern jmp_buf jabort; 29526049Sminshall char *tp; 29611353Ssam 29711650Ssam if (argc < 2) { 298*26497Sminshall (void) strcat(line, " "); 29911650Ssam printf("(local-files) "); 300*26497Sminshall (void) gets(&line[strlen(line)]); 30111650Ssam makeargv(); 30211650Ssam argc = margc; 30311650Ssam argv = margv; 30411353Ssam } 30511353Ssam if (argc < 2) { 30626049Sminshall printf("usage:%s local-files\n", argv[0]); 30726049Sminshall code = -1; 30811353Ssam return; 30911353Ssam } 31026049Sminshall mname = argv[0]; 31126049Sminshall mflag = 1; 31226049Sminshall oldintr = signal(SIGINT, mabort); 31326049Sminshall (void) setjmp(jabort); 31426049Sminshall if (proxy) { 31526049Sminshall char *cp, *tp2, tmpbuf[MAXPATHLEN]; 31626049Sminshall 317*26497Sminshall while ((cp = remglob(argv,0)) != NULL) { 31826049Sminshall if (*cp == 0) { 31926049Sminshall mflag = 0; 32026049Sminshall continue; 32126049Sminshall } 32226049Sminshall if (mflag && confirm(argv[0], cp)) { 32326049Sminshall tp = cp; 32426049Sminshall if (mcase) { 32526049Sminshall while (*tp && !islower(*tp)) { 32626049Sminshall tp++; 32726049Sminshall } 32826049Sminshall if (!*tp) { 32926049Sminshall tp = cp; 33026049Sminshall tp2 = tmpbuf; 33126049Sminshall while ((*tp2 = *tp) != NULL) { 33226049Sminshall if (isupper(*tp2)) { 33326049Sminshall *tp2 = 'a' + *tp2 - 'A'; 33426049Sminshall } 33526049Sminshall tp++; 33626049Sminshall tp2++; 33726049Sminshall } 33826049Sminshall } 33926049Sminshall tp = tmpbuf; 34026049Sminshall } 34126049Sminshall if (ntflag) { 34226049Sminshall tp = dotrans(tp); 34326049Sminshall } 34426049Sminshall if (mapflag) { 34526049Sminshall tp = domap(tp); 34626049Sminshall } 34726049Sminshall sendrequest((sunique) ? "STOU" : "STOR", cp,tp); 34826049Sminshall if (!mflag && fromatty) { 34926049Sminshall ointer = interactive; 35026049Sminshall interactive = 1; 35126049Sminshall if (confirm("Continue with","mput")) { 35226049Sminshall mflag++; 35326049Sminshall } 35426049Sminshall interactive = ointer; 35526049Sminshall } 35626049Sminshall } 35726049Sminshall } 35826049Sminshall (void) signal(SIGINT, oldintr); 35926049Sminshall mflag = 0; 36026049Sminshall return; 36126049Sminshall } 36213212Ssam for (i = 1; i < argc; i++) { 36313212Ssam register char **cpp, **gargs; 36413212Ssam 36513212Ssam if (!doglob) { 36626049Sminshall if (mflag && confirm(argv[0], argv[i])) { 36726049Sminshall tp = (ntflag) ? dotrans(argv[i]) : argv[i]; 36826049Sminshall tp = (mapflag) ? domap(tp) : tp; 36926049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 37026049Sminshall argv[i], tp); 37126049Sminshall if (!mflag && fromatty) { 37226049Sminshall ointer = interactive; 37326049Sminshall interactive = 1; 37426049Sminshall if (confirm("Continue with","mput")) { 37526049Sminshall mflag++; 37626049Sminshall } 37726049Sminshall interactive = ointer; 37826049Sminshall } 37926049Sminshall } 38013212Ssam continue; 38113212Ssam } 38213212Ssam gargs = glob(argv[i]); 38311650Ssam if (globerr != NULL) { 38411650Ssam printf("%s\n", globerr); 38511650Ssam if (gargs) 38611650Ssam blkfree(gargs); 38713212Ssam continue; 38811353Ssam } 38926049Sminshall for (cpp = gargs; cpp && *cpp != NULL; cpp++) { 39026049Sminshall if (mflag && confirm(argv[0], *cpp)) { 39126049Sminshall tp = (ntflag) ? dotrans(*cpp) : *cpp; 39226049Sminshall tp = (mapflag) ? domap(tp) : tp; 39326049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 39426049Sminshall *cpp, tp); 39526049Sminshall if (!mflag && fromatty) { 39626049Sminshall ointer = interactive; 39726049Sminshall interactive = 1; 39826049Sminshall if (confirm("Continue with","mput")) { 39926049Sminshall mflag++; 40026049Sminshall } 40126049Sminshall interactive = ointer; 40226049Sminshall } 40326049Sminshall } 40426049Sminshall } 40513212Ssam if (gargs != NULL) 40613212Ssam blkfree(gargs); 40711353Ssam } 40826049Sminshall (void) signal(SIGINT, oldintr); 40926049Sminshall mflag = 0; 41011353Ssam } 41111353Ssam 41211353Ssam /* 41311353Ssam * Receive one file. 41411353Ssam */ 41510294Ssam get(argc, argv) 41610294Ssam char *argv[]; 41710294Ssam { 41826049Sminshall int loc = 0; 41910294Ssam 42026049Sminshall if (argc == 2) { 42126049Sminshall argc++; 42226049Sminshall argv[2] = argv[1]; 42326049Sminshall loc++; 42426049Sminshall } 42510294Ssam if (argc < 2) { 426*26497Sminshall (void) strcat(line, " "); 42710294Ssam printf("(remote-file) "); 428*26497Sminshall (void) gets(&line[strlen(line)]); 42910294Ssam makeargv(); 43010294Ssam argc = margc; 43110294Ssam argv = margv; 43210294Ssam } 43310294Ssam if (argc < 2) { 43410294Ssam usage: 43526049Sminshall printf("usage: %s remote-file [ local-file ]\n", argv[0]); 43626049Sminshall code = -1; 43710294Ssam return; 43810294Ssam } 43910294Ssam if (argc < 3) { 440*26497Sminshall (void) strcat(line, " "); 44110294Ssam printf("(local-file) "); 442*26497Sminshall (void) gets(&line[strlen(line)]); 44310294Ssam makeargv(); 44410294Ssam argc = margc; 44510294Ssam argv = margv; 44610294Ssam } 44710294Ssam if (argc < 3) 44810294Ssam goto usage; 44926049Sminshall if (!globulize(&argv[2])) { 45026049Sminshall code = -1; 45111353Ssam return; 45226049Sminshall } 45326049Sminshall if (loc && mcase) { 45426049Sminshall char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN]; 45526049Sminshall 45626049Sminshall while (*tp && !islower(*tp)) { 45726049Sminshall tp++; 45826049Sminshall } 45926049Sminshall if (!*tp) { 46026049Sminshall tp = argv[2]; 46126049Sminshall tp2 = tmpbuf; 46226049Sminshall while ((*tp2 = *tp) != NULL) { 46326049Sminshall if (isupper(*tp2)) { 46426049Sminshall *tp2 = 'a' + *tp2 - 'A'; 46526049Sminshall } 46626049Sminshall tp++; 46726049Sminshall tp2++; 46826049Sminshall } 46926049Sminshall argv[2] = tmpbuf; 47026049Sminshall } 47126049Sminshall } 47226049Sminshall if (loc && ntflag) { 47326049Sminshall argv[2] = dotrans(argv[2]); 47426049Sminshall } 47526049Sminshall if (loc && mapflag) { 47626049Sminshall argv[2] = domap(argv[2]); 47726049Sminshall } 47811650Ssam recvrequest("RETR", argv[2], argv[1], "w"); 47910294Ssam } 48010294Ssam 48126049Sminshall mabort() 48226049Sminshall { 48326049Sminshall int ointer; 48426049Sminshall extern jmp_buf jabort; 48526049Sminshall 48626049Sminshall printf("\n"); 48726049Sminshall (void) fflush(stdout); 48826049Sminshall if (mflag && fromatty) { 48926049Sminshall ointer = interactive; 49026049Sminshall interactive = 1; 49126049Sminshall if (confirm("Continue with", mname)) { 49226049Sminshall interactive = ointer; 49326049Sminshall longjmp(jabort,0); 49426049Sminshall } 49526049Sminshall interactive = ointer; 49626049Sminshall } 49726049Sminshall mflag = 0; 49826049Sminshall longjmp(jabort,0); 49926049Sminshall } 50026049Sminshall 50111353Ssam /* 50211353Ssam * Get multiple files. 50311353Ssam */ 50411353Ssam mget(argc, argv) 50511353Ssam char *argv[]; 50611353Ssam { 50726049Sminshall char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN]; 50826049Sminshall int ointer, (*oldintr)(), mabort(); 50926049Sminshall extern jmp_buf jabort; 51011353Ssam 51111353Ssam if (argc < 2) { 512*26497Sminshall (void) strcat(line, " "); 51311756Ssam printf("(remote-files) "); 514*26497Sminshall (void) gets(&line[strlen(line)]); 51511353Ssam makeargv(); 51611353Ssam argc = margc; 51711353Ssam argv = margv; 51811353Ssam } 51911353Ssam if (argc < 2) { 52026049Sminshall printf("usage:%s remote-files\n", argv[0]); 52126049Sminshall code = -1; 52211353Ssam return; 52311353Ssam } 52426049Sminshall mname = argv[0]; 52526049Sminshall mflag = 1; 52626049Sminshall oldintr = signal(SIGINT,mabort); 52726049Sminshall (void) setjmp(jabort); 528*26497Sminshall while ((cp = remglob(argv,proxy)) != NULL) { 52926049Sminshall if (*cp == '\0') { 53026049Sminshall mflag = 0; 53126049Sminshall continue; 53226049Sminshall } 53326049Sminshall if (mflag && confirm(argv[0], cp)) { 53426049Sminshall tp = cp; 53526049Sminshall if (mcase) { 53626049Sminshall while (*tp && !islower(*tp)) { 53726049Sminshall tp++; 53826049Sminshall } 53926049Sminshall if (!*tp) { 54026049Sminshall tp = cp; 54126049Sminshall tp2 = tmpbuf; 54226049Sminshall while ((*tp2 = *tp) != NULL) { 54326049Sminshall if (isupper(*tp2)) { 54426049Sminshall *tp2 = 'a' + *tp2 - 'A'; 54526049Sminshall } 54626049Sminshall tp++; 54726049Sminshall tp2++; 54826049Sminshall } 54926049Sminshall } 55026049Sminshall tp = tmpbuf; 55126049Sminshall } 55226049Sminshall if (ntflag) { 55326049Sminshall tp = dotrans(tp); 55426049Sminshall } 55526049Sminshall if (mapflag) { 55626049Sminshall tp = domap(tp); 55726049Sminshall } 55826049Sminshall recvrequest("RETR", tp, cp, "w"); 55926049Sminshall if (!mflag && fromatty) { 56026049Sminshall ointer = interactive; 56126049Sminshall interactive = 1; 56226049Sminshall if (confirm("Continue with","mget")) { 56326049Sminshall mflag++; 56426049Sminshall } 56526049Sminshall interactive = ointer; 56626049Sminshall } 56726049Sminshall } 56826049Sminshall } 56926049Sminshall (void) signal(SIGINT,oldintr); 57026049Sminshall mflag = 0; 57111650Ssam } 57211650Ssam 57311650Ssam char * 574*26497Sminshall remglob(argv,doswitch) 57511650Ssam char *argv[]; 576*26497Sminshall int doswitch; 57711650Ssam { 57811756Ssam char temp[16]; 57911650Ssam static char buf[MAXPATHLEN]; 58011650Ssam static FILE *ftemp = NULL; 58111650Ssam static char **args; 58213212Ssam int oldverbose, oldhash; 58311756Ssam char *cp, *mode; 58411650Ssam 58526049Sminshall if (!mflag) { 58626049Sminshall if (!doglob) { 58726049Sminshall args = NULL; 58826049Sminshall } 58926049Sminshall else { 59026049Sminshall if (ftemp) { 591*26497Sminshall (void) fclose(ftemp); 59226049Sminshall ftemp = NULL; 59326049Sminshall } 59426049Sminshall } 59526049Sminshall return(NULL); 59626049Sminshall } 59711650Ssam if (!doglob) { 59811756Ssam if (args == NULL) 59911650Ssam args = argv; 60011650Ssam if ((cp = *++args) == NULL) 60111650Ssam args = NULL; 60211650Ssam return (cp); 60311353Ssam } 60411650Ssam if (ftemp == NULL) { 605*26497Sminshall (void) strcpy(temp, "/tmp/ftpXXXXXX"); 606*26497Sminshall (void) mktemp(temp); 60711650Ssam oldverbose = verbose, verbose = 0; 60813212Ssam oldhash = hash, hash = 0; 60926049Sminshall if (doswitch) { 61026049Sminshall pswitch(!proxy); 61126049Sminshall } 61211756Ssam for (mode = "w"; *++argv != NULL; mode = "a") 61311756Ssam recvrequest ("NLST", temp, *argv, mode); 61426049Sminshall if (doswitch) { 61526049Sminshall pswitch(!proxy); 61626049Sminshall } 61713212Ssam verbose = oldverbose; hash = oldhash; 61811650Ssam ftemp = fopen(temp, "r"); 619*26497Sminshall (void) unlink(temp); 62011650Ssam if (ftemp == NULL) { 62111650Ssam printf("can't find list of remote files, oops\n"); 62211756Ssam return (NULL); 62311353Ssam } 62411353Ssam } 62511650Ssam if (fgets(buf, sizeof (buf), ftemp) == NULL) { 626*26497Sminshall (void) fclose(ftemp), ftemp = NULL; 62711650Ssam return (NULL); 62811353Ssam } 62911650Ssam if ((cp = index(buf, '\n')) != NULL) 63011650Ssam *cp = '\0'; 63111650Ssam return (buf); 63211353Ssam } 63311353Ssam 63410294Ssam char * 63510294Ssam onoff(bool) 63610294Ssam int bool; 63710294Ssam { 63810294Ssam 63910294Ssam return (bool ? "on" : "off"); 64010294Ssam } 64110294Ssam 64210294Ssam /* 64310294Ssam * Show status. 64410294Ssam */ 645*26497Sminshall /*ARGSUSED*/ 64610294Ssam status(argc, argv) 64710294Ssam char *argv[]; 64810294Ssam { 64926049Sminshall int i; 65010294Ssam 65110294Ssam if (connected) 65210294Ssam printf("Connected to %s.\n", hostname); 65310294Ssam else 65410294Ssam printf("Not connected.\n"); 65526049Sminshall if (!proxy) { 65626049Sminshall pswitch(1); 65726049Sminshall if (connected) { 65826049Sminshall printf("Connected for proxy commands to %s.\n", hostname); 65926049Sminshall } 66026049Sminshall else { 66126049Sminshall printf("No proxy connection.\n"); 66226049Sminshall } 66326049Sminshall pswitch(0); 66426049Sminshall } 66510294Ssam printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n", 66610294Ssam modename, typename, formname, structname); 66711353Ssam printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 66811353Ssam onoff(verbose), onoff(bell), onoff(interactive), 66911353Ssam onoff(doglob)); 67026049Sminshall printf("Store unique: %s; Receive unique: %s\n", onoff(sunique), 67126049Sminshall onoff(runique)); 67226049Sminshall printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag)); 67326049Sminshall if (ntflag) { 67426049Sminshall printf("Ntrans: (in) %s (out) %s\n", ntin,ntout); 67526049Sminshall } 67626049Sminshall else { 67726049Sminshall printf("Ntrans: off\n"); 67826049Sminshall } 67926049Sminshall if (mapflag) { 68026049Sminshall printf("Nmap: (in) %s (out) %s\n", mapin, mapout); 68126049Sminshall } 68226049Sminshall else { 68326049Sminshall printf("Nmap: off\n"); 68426049Sminshall } 68514143Ssam printf("Hash mark printing: %s; Use of PORT cmds: %s\n", 68614143Ssam onoff(hash), onoff(sendport)); 68726049Sminshall if (macnum > 0) { 68826049Sminshall printf("Macros:\n"); 68926049Sminshall for (i=0; i<macnum; i++) { 69026049Sminshall printf("\t%s\n",macros[i].mac_name); 69126049Sminshall } 69226049Sminshall } 69326049Sminshall code = 0; 69410294Ssam } 69510294Ssam 69610294Ssam /* 69710294Ssam * Set beep on cmd completed mode. 69810294Ssam */ 69910294Ssam /*VARARGS*/ 70010294Ssam setbell() 70110294Ssam { 70210294Ssam 70310294Ssam bell = !bell; 70410294Ssam printf("Bell mode %s.\n", onoff(bell)); 70526049Sminshall code = bell; 70610294Ssam } 70710294Ssam 70810294Ssam /* 70910294Ssam * Turn on packet tracing. 71010294Ssam */ 71110294Ssam /*VARARGS*/ 71210294Ssam settrace() 71310294Ssam { 71410294Ssam 71510294Ssam trace = !trace; 71610294Ssam printf("Packet tracing %s.\n", onoff(trace)); 71726049Sminshall code = trace; 71810294Ssam } 71910294Ssam 72010294Ssam /* 72111650Ssam * Toggle hash mark printing during transfers. 72211650Ssam */ 72311650Ssam /*VARARGS*/ 72411650Ssam sethash() 72511650Ssam { 72611650Ssam 72711650Ssam hash = !hash; 72811650Ssam printf("Hash mark printing %s", onoff(hash)); 72926049Sminshall code = hash; 73011650Ssam if (hash) 73111650Ssam printf(" (%d bytes/hash mark)", BUFSIZ); 73211650Ssam printf(".\n"); 73311650Ssam } 73411650Ssam 73511650Ssam /* 73610294Ssam * Turn on printing of server echo's. 73710294Ssam */ 73810294Ssam /*VARARGS*/ 73910294Ssam setverbose() 74010294Ssam { 74110294Ssam 74210294Ssam verbose = !verbose; 74310294Ssam printf("Verbose mode %s.\n", onoff(verbose)); 74426049Sminshall code = verbose; 74510294Ssam } 74610294Ssam 74710294Ssam /* 74811650Ssam * Toggle PORT cmd use before each data connection. 74911650Ssam */ 75011650Ssam /*VARARGS*/ 75111650Ssam setport() 75211650Ssam { 75311650Ssam 75411650Ssam sendport = !sendport; 75511650Ssam printf("Use of PORT cmds %s.\n", onoff(sendport)); 75626049Sminshall code = sendport; 75711650Ssam } 75811650Ssam 75911650Ssam /* 76010294Ssam * Turn on interactive prompting 76110294Ssam * during mget, mput, and mdelete. 76210294Ssam */ 76310294Ssam /*VARARGS*/ 76410294Ssam setprompt() 76510294Ssam { 76610294Ssam 76710294Ssam interactive = !interactive; 76810294Ssam printf("Interactive mode %s.\n", onoff(interactive)); 76926049Sminshall code = interactive; 77010294Ssam } 77110294Ssam 77210294Ssam /* 77311353Ssam * Toggle metacharacter interpretation 77411353Ssam * on local file names. 77511353Ssam */ 77611353Ssam /*VARARGS*/ 77711353Ssam setglob() 77811353Ssam { 77911353Ssam 78011353Ssam doglob = !doglob; 78111353Ssam printf("Globbing %s.\n", onoff(doglob)); 78226049Sminshall code = doglob; 78311353Ssam } 78411353Ssam 78511353Ssam /* 78610294Ssam * Set debugging mode on/off and/or 78710294Ssam * set level of debugging. 78810294Ssam */ 78911756Ssam /*VARARGS*/ 79010294Ssam setdebug(argc, argv) 79110294Ssam char *argv[]; 79210294Ssam { 79310294Ssam int val; 79410294Ssam 79510294Ssam if (argc > 1) { 79610294Ssam val = atoi(argv[1]); 79710294Ssam if (val < 0) { 79810294Ssam printf("%s: bad debugging value.\n", argv[1]); 79926049Sminshall code = -1; 80010294Ssam return; 80110294Ssam } 80210294Ssam } else 80310294Ssam val = !debug; 80410294Ssam debug = val; 80510294Ssam if (debug) 80610294Ssam options |= SO_DEBUG; 80710294Ssam else 80810294Ssam options &= ~SO_DEBUG; 80910294Ssam printf("Debugging %s (debug=%d).\n", onoff(debug), debug); 81026049Sminshall code = debug > 0; 81110294Ssam } 81210294Ssam 81310294Ssam /* 81410294Ssam * Set current working directory 81510294Ssam * on remote machine. 81610294Ssam */ 81710294Ssam cd(argc, argv) 81810294Ssam char *argv[]; 81910294Ssam { 82010294Ssam 82110294Ssam if (argc < 2) { 822*26497Sminshall (void) strcat(line, " "); 82310294Ssam printf("(remote-directory) "); 824*26497Sminshall (void) gets(&line[strlen(line)]); 82510294Ssam makeargv(); 82610294Ssam argc = margc; 82710294Ssam argv = margv; 82810294Ssam } 82910294Ssam if (argc < 2) { 83026049Sminshall printf("usage:%s remote-directory\n", argv[0]); 83126049Sminshall code = -1; 83210294Ssam return; 83310294Ssam } 83410294Ssam (void) command("CWD %s", argv[1]); 83510294Ssam } 83610294Ssam 83710294Ssam /* 83810294Ssam * Set current working directory 83910294Ssam * on local machine. 84010294Ssam */ 84110294Ssam lcd(argc, argv) 84210294Ssam char *argv[]; 84310294Ssam { 84411353Ssam char buf[MAXPATHLEN]; 84510294Ssam 84611353Ssam if (argc < 2) 84711353Ssam argc++, argv[1] = home; 84810294Ssam if (argc != 2) { 84926049Sminshall printf("usage:%s local-directory\n", argv[0]); 85026049Sminshall code = -1; 85110294Ssam return; 85210294Ssam } 85326049Sminshall if (!globulize(&argv[1])) { 85426049Sminshall code = -1; 85511353Ssam return; 85626049Sminshall } 85711353Ssam if (chdir(argv[1]) < 0) { 85810294Ssam perror(argv[1]); 85926049Sminshall code = -1; 86011353Ssam return; 86111353Ssam } 86211353Ssam printf("Local directory now %s\n", getwd(buf)); 86326049Sminshall code = 0; 86410294Ssam } 86510294Ssam 86610294Ssam /* 86710294Ssam * Delete a single file. 86810294Ssam */ 86910294Ssam delete(argc, argv) 87010294Ssam char *argv[]; 87110294Ssam { 87210294Ssam 87310294Ssam if (argc < 2) { 874*26497Sminshall (void) strcat(line, " "); 87510294Ssam printf("(remote-file) "); 876*26497Sminshall (void) gets(&line[strlen(line)]); 87710294Ssam makeargv(); 87810294Ssam argc = margc; 87910294Ssam argv = margv; 88010294Ssam } 88110294Ssam if (argc < 2) { 88226049Sminshall printf("usage:%s remote-file\n", argv[0]); 88326049Sminshall code = -1; 88410294Ssam return; 88510294Ssam } 88610294Ssam (void) command("DELE %s", argv[1]); 88710294Ssam } 88810294Ssam 88910294Ssam /* 89011650Ssam * Delete multiple files. 89111650Ssam */ 89211650Ssam mdelete(argc, argv) 89311650Ssam char *argv[]; 89411650Ssam { 89511650Ssam char *cp; 89626049Sminshall int ointer, (*oldintr)(), mabort(); 89726049Sminshall extern jmp_buf jabort; 89811650Ssam 89911650Ssam if (argc < 2) { 900*26497Sminshall (void) strcat(line, " "); 90111650Ssam printf("(remote-files) "); 902*26497Sminshall (void) gets(&line[strlen(line)]); 90311650Ssam makeargv(); 90411650Ssam argc = margc; 90511650Ssam argv = margv; 90611650Ssam } 90711650Ssam if (argc < 2) { 90826049Sminshall printf("usage:%s remote-files\n", argv[0]); 90926049Sminshall code = -1; 91011650Ssam return; 91111650Ssam } 91226049Sminshall mname = argv[0]; 91326049Sminshall mflag = 1; 91426049Sminshall oldintr = signal(SIGINT, mabort); 91526049Sminshall (void) setjmp(jabort); 916*26497Sminshall while ((cp = remglob(argv,0)) != NULL) { 91726049Sminshall if (*cp == '\0') { 91826049Sminshall mflag = 0; 91926049Sminshall continue; 92026049Sminshall } 92126049Sminshall if (mflag && confirm(argv[0], cp)) { 92211650Ssam (void) command("DELE %s", cp); 92326049Sminshall if (!mflag && fromatty) { 92426049Sminshall ointer = interactive; 92526049Sminshall interactive = 1; 92626049Sminshall if (confirm("Continue with", "mdelete")) { 92726049Sminshall mflag++; 92826049Sminshall } 92926049Sminshall interactive = ointer; 93026049Sminshall } 93126049Sminshall } 93226049Sminshall } 93326049Sminshall (void) signal(SIGINT, oldintr); 93426049Sminshall mflag = 0; 93511650Ssam } 93611756Ssam 93711650Ssam /* 93810294Ssam * Rename a remote file. 93910294Ssam */ 94010294Ssam renamefile(argc, argv) 94110294Ssam char *argv[]; 94210294Ssam { 94310294Ssam 94410294Ssam if (argc < 2) { 945*26497Sminshall (void) strcat(line, " "); 94610294Ssam printf("(from-name) "); 947*26497Sminshall (void) gets(&line[strlen(line)]); 94810294Ssam makeargv(); 94910294Ssam argc = margc; 95010294Ssam argv = margv; 95110294Ssam } 95210294Ssam if (argc < 2) { 95310294Ssam usage: 95410294Ssam printf("%s from-name to-name\n", argv[0]); 95526049Sminshall code = -1; 95610294Ssam return; 95710294Ssam } 95810294Ssam if (argc < 3) { 959*26497Sminshall (void) strcat(line, " "); 96010294Ssam printf("(to-name) "); 961*26497Sminshall (void) gets(&line[strlen(line)]); 96210294Ssam makeargv(); 96310294Ssam argc = margc; 96410294Ssam argv = margv; 96510294Ssam } 96610294Ssam if (argc < 3) 96710294Ssam goto usage; 96810294Ssam if (command("RNFR %s", argv[1]) == CONTINUE) 96910294Ssam (void) command("RNTO %s", argv[2]); 97010294Ssam } 97110294Ssam 97210294Ssam /* 97310294Ssam * Get a directory listing 97410294Ssam * of remote files. 97510294Ssam */ 97610294Ssam ls(argc, argv) 97710294Ssam char *argv[]; 97810294Ssam { 97911756Ssam char *cmd; 98010294Ssam 98110294Ssam if (argc < 2) 98210294Ssam argc++, argv[1] = NULL; 98310294Ssam if (argc < 3) 98410294Ssam argc++, argv[2] = "-"; 98511756Ssam if (argc > 3) { 98611756Ssam printf("usage: %s remote-directory local-file\n", argv[0]); 98726049Sminshall code = -1; 98811756Ssam return; 98911756Ssam } 99010294Ssam cmd = argv[0][0] == 'l' ? "NLST" : "LIST"; 99126049Sminshall if (strcmp(argv[2], "-") && !globulize(&argv[2])) { 99226049Sminshall code = -1; 99311353Ssam return; 99426049Sminshall } 99511756Ssam recvrequest(cmd, argv[2], argv[1], "w"); 99610294Ssam } 99710294Ssam 99810294Ssam /* 99911756Ssam * Get a directory listing 100011756Ssam * of multiple remote files. 100111756Ssam */ 100211756Ssam mls(argc, argv) 100311756Ssam char *argv[]; 100411756Ssam { 100526049Sminshall char *cmd, mode[1], *dest; 100626049Sminshall int ointer, i, (*oldintr)(), mabort(); 100726049Sminshall extern jmp_buf jabort; 100811756Ssam 100913212Ssam if (argc < 2) { 1010*26497Sminshall (void) strcat(line, " "); 101113212Ssam printf("(remote-files) "); 1012*26497Sminshall (void) gets(&line[strlen(line)]); 101313212Ssam makeargv(); 101413212Ssam argc = margc; 101513212Ssam argv = margv; 101613212Ssam } 101713212Ssam if (argc < 3) { 1018*26497Sminshall (void) strcat(line, " "); 101913212Ssam printf("(local-file) "); 1020*26497Sminshall (void) gets(&line[strlen(line)]); 102113212Ssam makeargv(); 102213212Ssam argc = margc; 102313212Ssam argv = margv; 102413212Ssam } 102513212Ssam if (argc < 3) { 102626049Sminshall printf("usage:%s remote-files local-file\n", argv[0]); 102726049Sminshall code = -1; 102813212Ssam return; 102913212Ssam } 103013212Ssam dest = argv[argc - 1]; 103113212Ssam argv[argc - 1] = NULL; 103226049Sminshall if (strcmp(dest, "-") && *dest != '|') 103326049Sminshall if (!globulize(&dest) || !confirm("output to local-file:", dest)) { 103426049Sminshall code = -1; 103513212Ssam return; 103626049Sminshall } 103711756Ssam cmd = argv[0][1] == 'l' ? "NLST" : "LIST"; 103826049Sminshall mname = argv[0]; 103926049Sminshall mflag = 1; 104026049Sminshall oldintr = signal(SIGINT, mabort); 104126049Sminshall (void) setjmp(jabort); 104226049Sminshall for (i = 1; mflag && i < argc-1; ++i) { 104326049Sminshall *mode = (i == 1) ? 'w' : 'a'; 104426049Sminshall recvrequest(cmd, dest, argv[i], mode); 104526049Sminshall if (!mflag && fromatty) { 104626049Sminshall ointer = interactive; 104726049Sminshall interactive = 1; 104826049Sminshall if (confirm("Continue with", argv[0])) { 104926049Sminshall mflag ++; 105026049Sminshall } 105126049Sminshall interactive = ointer; 105226049Sminshall } 105326049Sminshall } 105426049Sminshall (void) signal(SIGINT, oldintr); 105526049Sminshall mflag = 0; 105611756Ssam } 105711756Ssam 105811756Ssam /* 105910294Ssam * Do a shell escape 106010294Ssam */ 1061*26497Sminshall /*ARGSUSED*/ 106210294Ssam shell(argc, argv) 106310294Ssam char *argv[]; 106410294Ssam { 1065*26497Sminshall int pid, (*old1)(), (*old2)(); 106626049Sminshall char shellnam[40], *shell, *namep; 1067*26497Sminshall union wait status; 106810294Ssam 106911756Ssam old1 = signal (SIGINT, SIG_IGN); 107011756Ssam old2 = signal (SIGQUIT, SIG_IGN); 107111756Ssam if ((pid = fork()) == 0) { 107211756Ssam for (pid = 3; pid < 20; pid++) 1073*26497Sminshall (void) close(pid); 1074*26497Sminshall (void) signal(SIGINT, SIG_DFL); 1075*26497Sminshall (void) signal(SIGQUIT, SIG_DFL); 107625908Smckusick shell = getenv("SHELL"); 107725908Smckusick if (shell == NULL) 107825908Smckusick shell = "/bin/sh"; 107925908Smckusick namep = rindex(shell,'/'); 108025908Smckusick if (namep == NULL) 108125908Smckusick namep = shell; 1082*26497Sminshall (void) strcpy(shellnam,"-"); 1083*26497Sminshall (void) strcat(shellnam, ++namep); 108426049Sminshall if (strcmp(namep, "sh") != 0) 108526049Sminshall shellnam[0] = '+'; 108626049Sminshall if (debug) { 108726049Sminshall printf ("%s\n", shell); 1088*26497Sminshall (void) fflush (stdout); 108911756Ssam } 109026049Sminshall if (argc > 1) { 109126049Sminshall execl(shell,shellnam,"-c",altarg,(char *)0); 109226049Sminshall } 109326049Sminshall else { 109426049Sminshall execl(shell,shellnam,(char *)0); 109526049Sminshall } 109625908Smckusick perror(shell); 109726049Sminshall code = -1; 109811756Ssam exit(1); 109926049Sminshall } 110011756Ssam if (pid > 0) 110111756Ssam while (wait(&status) != pid) 110211756Ssam ; 1103*26497Sminshall (void) signal(SIGINT, old1); 1104*26497Sminshall (void) signal(SIGQUIT, old2); 110526049Sminshall if (pid == -1) { 110611756Ssam perror("Try again later"); 110726049Sminshall code = -1; 110826049Sminshall } 110926049Sminshall else { 111026049Sminshall code = 0; 111126049Sminshall } 111211756Ssam return (0); 111310294Ssam } 111410294Ssam 111510294Ssam /* 111610294Ssam * Send new user information (re-login) 111710294Ssam */ 111810294Ssam user(argc, argv) 111910294Ssam int argc; 112010294Ssam char **argv; 112110294Ssam { 1122*26497Sminshall char acct[80], *mygetpass(); 112326049Sminshall int n, aflag = 0; 112410294Ssam 112510294Ssam if (argc < 2) { 1126*26497Sminshall (void) strcat(line, " "); 112710294Ssam printf("(username) "); 1128*26497Sminshall (void) gets(&line[strlen(line)]); 112910294Ssam makeargv(); 113010294Ssam argc = margc; 113110294Ssam argv = margv; 113210294Ssam } 113310294Ssam if (argc > 4) { 113410294Ssam printf("usage: %s username [password] [account]\n", argv[0]); 113526049Sminshall code = -1; 113611756Ssam return (0); 113710294Ssam } 113810294Ssam n = command("USER %s", argv[1]); 113910294Ssam if (n == CONTINUE) { 114010294Ssam if (argc < 3 ) 1141*26497Sminshall argv[2] = mygetpass("Password: "), argc++; 114210294Ssam n = command("PASS %s", argv[2]); 114310294Ssam } 114410294Ssam if (n == CONTINUE) { 114510294Ssam if (argc < 4) { 114610294Ssam printf("Account: "); (void) fflush(stdout); 114710294Ssam (void) fgets(acct, sizeof(acct) - 1, stdin); 114810294Ssam acct[strlen(acct) - 1] = '\0'; 114910294Ssam argv[3] = acct; argc++; 115010294Ssam } 115126049Sminshall n = command("ACCT %s", argv[3]); 115226049Sminshall aflag++; 115310294Ssam } 115410294Ssam if (n != COMPLETE) { 1155*26497Sminshall fprintf(stdout, "Login failed.\n"); 115610294Ssam return (0); 115710294Ssam } 115826049Sminshall if (!aflag && argc == 4) { 115926049Sminshall (void) command("ACCT %s", argv[3]); 116026049Sminshall } 116110294Ssam return (1); 116210294Ssam } 116310294Ssam 116410294Ssam /* 116510294Ssam * Print working directory. 116610294Ssam */ 116710294Ssam /*VARARGS*/ 116810294Ssam pwd() 116910294Ssam { 117011756Ssam 117126049Sminshall (void) command("PWD"); 117210294Ssam } 117310294Ssam 117410294Ssam /* 117510294Ssam * Make a directory. 117610294Ssam */ 117710294Ssam makedir(argc, argv) 117810294Ssam char *argv[]; 117910294Ssam { 118010294Ssam 118110294Ssam if (argc < 2) { 1182*26497Sminshall (void) strcat(line, " "); 118310294Ssam printf("(directory-name) "); 1184*26497Sminshall (void) gets(&line[strlen(line)]); 118510294Ssam makeargv(); 118610294Ssam argc = margc; 118710294Ssam argv = margv; 118810294Ssam } 118910294Ssam if (argc < 2) { 119026049Sminshall printf("usage: %s directory-name\n", argv[0]); 119126049Sminshall code = -1; 119210294Ssam return; 119310294Ssam } 119426049Sminshall (void) command("MKD %s", argv[1]); 119510294Ssam } 119610294Ssam 119710294Ssam /* 119810294Ssam * Remove a directory. 119910294Ssam */ 120010294Ssam removedir(argc, argv) 120110294Ssam char *argv[]; 120210294Ssam { 120310294Ssam 120410294Ssam if (argc < 2) { 1205*26497Sminshall (void) strcat(line, " "); 120610294Ssam printf("(directory-name) "); 1207*26497Sminshall (void) gets(&line[strlen(line)]); 120810294Ssam makeargv(); 120910294Ssam argc = margc; 121010294Ssam argv = margv; 121110294Ssam } 121210294Ssam if (argc < 2) { 121326049Sminshall printf("usage: %s directory-name\n", argv[0]); 121426049Sminshall code = -1; 121510294Ssam return; 121610294Ssam } 121726049Sminshall (void) command("RMD %s", argv[1]); 121810294Ssam } 121910294Ssam 122010294Ssam /* 122110294Ssam * Send a line, verbatim, to the remote machine. 122210294Ssam */ 122310294Ssam quote(argc, argv) 122410294Ssam char *argv[]; 122510294Ssam { 122610294Ssam int i; 122710294Ssam char buf[BUFSIZ]; 122810294Ssam 122910294Ssam if (argc < 2) { 1230*26497Sminshall (void) strcat(line, " "); 123110294Ssam printf("(command line to send) "); 1232*26497Sminshall (void) gets(&line[strlen(line)]); 123310294Ssam makeargv(); 123410294Ssam argc = margc; 123510294Ssam argv = margv; 123610294Ssam } 123710294Ssam if (argc < 2) { 123810294Ssam printf("usage: %s line-to-send\n", argv[0]); 123926049Sminshall code = -1; 124010294Ssam return; 124110294Ssam } 1242*26497Sminshall (void) strcpy(buf, argv[1]); 124310294Ssam for (i = 2; i < argc; i++) { 1244*26497Sminshall (void) strcat(buf, " "); 1245*26497Sminshall (void) strcat(buf, argv[i]); 124610294Ssam } 124726049Sminshall if (command(buf) == PRELIM) { 124826049Sminshall while (getreply(0) == PRELIM); 124926049Sminshall } 125010294Ssam } 125110294Ssam 125210294Ssam /* 125310294Ssam * Ask the other side for help. 125410294Ssam */ 125510294Ssam rmthelp(argc, argv) 125610294Ssam char *argv[]; 125710294Ssam { 125810294Ssam int oldverbose = verbose; 125910294Ssam 126010294Ssam verbose = 1; 126110294Ssam (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]); 126210294Ssam verbose = oldverbose; 126310294Ssam } 126410294Ssam 126510294Ssam /* 126610294Ssam * Terminate session and exit. 126710294Ssam */ 126810294Ssam /*VARARGS*/ 126910294Ssam quit() 127010294Ssam { 127110294Ssam 127218286Sralph if (connected) 127318286Sralph disconnect(); 127426049Sminshall pswitch(1); 127526049Sminshall if (connected) { 127626049Sminshall disconnect(); 127726049Sminshall } 127810294Ssam exit(0); 127910294Ssam } 128010294Ssam 128110294Ssam /* 128210294Ssam * Terminate session, but don't exit. 128310294Ssam */ 128410294Ssam disconnect() 128510294Ssam { 128610294Ssam extern FILE *cout; 128710294Ssam extern int data; 128810294Ssam 128910294Ssam if (!connected) 129010294Ssam return; 129110294Ssam (void) command("QUIT"); 129226049Sminshall if (cout) { 129326049Sminshall (void) fclose(cout); 129426049Sminshall } 129510294Ssam cout = NULL; 129610294Ssam connected = 0; 129710294Ssam data = -1; 129826049Sminshall if (!proxy) { 129926049Sminshall macnum = 0; 130026049Sminshall } 130110294Ssam } 130211353Ssam 130311650Ssam confirm(cmd, file) 130411353Ssam char *cmd, *file; 130511353Ssam { 130611353Ssam char line[BUFSIZ]; 130711353Ssam 130811353Ssam if (!interactive) 130911650Ssam return (1); 131011353Ssam printf("%s %s? ", cmd, file); 1311*26497Sminshall (void) fflush(stdout); 1312*26497Sminshall (void) gets(line); 131311650Ssam return (*line != 'n' && *line != 'N'); 131411353Ssam } 131511353Ssam 131611353Ssam fatal(msg) 131711353Ssam char *msg; 131811353Ssam { 131911353Ssam 1320*26497Sminshall fprintf(stderr, "ftp: %s\n", msg); 132111353Ssam exit(1); 132211353Ssam } 132311353Ssam 132411353Ssam /* 132511353Ssam * Glob a local file name specification with 132611353Ssam * the expectation of a single return value. 132711353Ssam * Can't control multiple values being expanded 132811353Ssam * from the expression, we return only the first. 132911353Ssam */ 133011353Ssam globulize(cpp) 133111353Ssam char **cpp; 133211353Ssam { 133311353Ssam char **globbed; 133411353Ssam 133511353Ssam if (!doglob) 133611353Ssam return (1); 133711353Ssam globbed = glob(*cpp); 133811353Ssam if (globerr != NULL) { 133911353Ssam printf("%s: %s\n", *cpp, globerr); 134011353Ssam if (globbed) 134111353Ssam blkfree(globbed); 134211353Ssam return (0); 134311353Ssam } 134411353Ssam if (globbed) { 134511353Ssam *cpp = *globbed++; 134611353Ssam /* don't waste too much memory */ 134711353Ssam if (*globbed) 134811353Ssam blkfree(globbed); 134911353Ssam } 135011353Ssam return (1); 135111353Ssam } 135226049Sminshall 135326049Sminshall account(argc,argv) 135426049Sminshall 135526049Sminshall int argc; 135626049Sminshall char **argv; 135726049Sminshall { 1358*26497Sminshall char acct[50], *mygetpass(), *ap; 135926049Sminshall 136026049Sminshall if (argc > 1) { 136126049Sminshall ++argv; 136226049Sminshall --argc; 136326049Sminshall (void) strncpy(acct,*argv,49); 136426049Sminshall acct[50] = '\0'; 136526049Sminshall while (argc > 1) { 136626049Sminshall --argc; 136726049Sminshall ++argv; 136826049Sminshall (void) strncat(acct,*argv, 49-strlen(acct)); 136926049Sminshall } 137026049Sminshall ap = acct; 137126049Sminshall } 137226049Sminshall else { 1373*26497Sminshall ap = mygetpass("Account:"); 137426049Sminshall } 137526049Sminshall (void) command("ACCT %s", ap); 137626049Sminshall } 137726049Sminshall 137826049Sminshall jmp_buf abortprox; 137926049Sminshall 138026049Sminshall proxabort() 138126049Sminshall { 138226049Sminshall extern int proxy; 138326049Sminshall 138426049Sminshall if (!proxy) { 138526049Sminshall pswitch(1); 138626049Sminshall } 138726049Sminshall if (connected) { 138826049Sminshall proxflag = 1; 138926049Sminshall } 139026049Sminshall else { 139126049Sminshall proxflag = 0; 139226049Sminshall } 139326049Sminshall pswitch(0); 139426049Sminshall longjmp(abortprox,1); 139526049Sminshall } 139626049Sminshall 139726049Sminshall doproxy(argc,argv) 139826049Sminshall int argc; 139926049Sminshall char *argv[]; 140026049Sminshall { 140126049Sminshall int (*oldintr)(), proxabort(); 140226049Sminshall register struct cmd *c; 140326049Sminshall struct cmd *getcmd(); 140426049Sminshall extern struct cmd cmdtab[]; 140526049Sminshall extern jmp_buf abortprox; 140626049Sminshall 140726049Sminshall if (argc < 2) { 1408*26497Sminshall (void) strcat(line, " "); 140926049Sminshall printf("(command) "); 1410*26497Sminshall (void) gets(&line[strlen(line)]); 141126049Sminshall makeargv(); 141226049Sminshall argc = margc; 141326049Sminshall argv = margv; 141426049Sminshall } 141526049Sminshall if (argc < 2) { 141626049Sminshall printf("usage:%s command\n", argv[0]); 141726049Sminshall code = -1; 141826049Sminshall return; 141926049Sminshall } 142026049Sminshall c = getcmd(argv[1]); 142126049Sminshall if (c == (struct cmd *) -1) { 142226049Sminshall printf("?Ambiguous command\n"); 1423*26497Sminshall (void) fflush(stdout); 142426049Sminshall code = -1; 142526049Sminshall return; 142626049Sminshall } 142726049Sminshall if (c == 0) { 142826049Sminshall printf("?Invalid command\n"); 1429*26497Sminshall (void) fflush(stdout); 143026049Sminshall code = -1; 143126049Sminshall return; 143226049Sminshall } 143326049Sminshall if (!c->c_proxy) { 143426049Sminshall printf("?Invalid proxy command\n"); 1435*26497Sminshall (void) fflush(stdout); 143626049Sminshall code = -1; 143726049Sminshall return; 143826049Sminshall } 143926049Sminshall if (setjmp(abortprox)) { 144026049Sminshall code = -1; 144126049Sminshall return; 144226049Sminshall } 144326049Sminshall oldintr = signal(SIGINT, proxabort); 144426049Sminshall pswitch(1); 144526049Sminshall if (c->c_conn && !connected) { 144626049Sminshall printf("Not connected\n"); 1447*26497Sminshall (void) fflush(stdout); 144826049Sminshall pswitch(0); 144926049Sminshall (void) signal(SIGINT, oldintr); 145026049Sminshall code = -1; 145126049Sminshall return; 145226049Sminshall } 145326049Sminshall (*c->c_handler)(argc-1, argv+1); 145426049Sminshall if (connected) { 145526049Sminshall proxflag = 1; 145626049Sminshall } 145726049Sminshall else { 145826049Sminshall proxflag = 0; 145926049Sminshall } 146026049Sminshall pswitch(0); 146126049Sminshall (void) signal(SIGINT, oldintr); 146226049Sminshall } 146326049Sminshall 146426049Sminshall setcase() 146526049Sminshall { 146626049Sminshall mcase = !mcase; 146726049Sminshall printf("Case mapping %s.\n", onoff(mcase)); 146826049Sminshall code = mcase; 146926049Sminshall } 147026049Sminshall 147126049Sminshall setcr() 147226049Sminshall { 147326049Sminshall crflag = !crflag; 147426049Sminshall printf("Carriage Return stripping %s.\n", onoff(crflag)); 147526049Sminshall code = crflag; 147626049Sminshall } 147726049Sminshall 147826049Sminshall setntrans(argc,argv) 147926049Sminshall int argc; 148026049Sminshall char *argv[]; 148126049Sminshall { 148226049Sminshall if (argc == 1) { 148326049Sminshall ntflag = 0; 148426049Sminshall printf("Ntrans off.\n"); 148526049Sminshall code = ntflag; 148626049Sminshall return; 148726049Sminshall } 148826049Sminshall ntflag++; 148926049Sminshall code = ntflag; 149026049Sminshall (void) strncpy(ntin, argv[1], 16); 149126049Sminshall ntin[16] = '\0'; 149226049Sminshall if (argc == 2) { 149326049Sminshall ntout[0] = '\0'; 149426049Sminshall return; 149526049Sminshall } 149626049Sminshall (void) strncpy(ntout, argv[2], 16); 149726049Sminshall ntout[16] = '\0'; 149826049Sminshall } 149926049Sminshall 150026049Sminshall char * 150126049Sminshall dotrans(name) 150226049Sminshall char *name; 150326049Sminshall { 150426049Sminshall static char new[MAXPATHLEN]; 150526049Sminshall char *cp1, *cp2 = new; 150626049Sminshall register int i, ostop, found; 150726049Sminshall 150826049Sminshall for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++); 150926049Sminshall for (cp1 = name; *cp1; cp1++) { 151026049Sminshall found = 0; 151126049Sminshall for (i = 0; *(ntin + i) && i < 16; i++) { 151226049Sminshall if (*cp1 == *(ntin + i)) { 151326049Sminshall found++; 151426049Sminshall if (i < ostop) { 151526049Sminshall *cp2++ = *(ntout + i); 151626049Sminshall } 151726049Sminshall break; 151826049Sminshall } 151926049Sminshall } 152026049Sminshall if (!found) { 152126049Sminshall *cp2++ = *cp1; 152226049Sminshall } 152326049Sminshall } 152426049Sminshall *cp2 = '\0'; 152526049Sminshall return(new); 152626049Sminshall } 152726049Sminshall 152826049Sminshall setnmap(argc, argv) 152926049Sminshall int argc; 153026049Sminshall char *argv[]; 153126049Sminshall { 153226049Sminshall char *cp; 153326049Sminshall 153426049Sminshall if (argc == 1) { 153526049Sminshall mapflag = 0; 153626049Sminshall printf("Nmap off.\n"); 153726049Sminshall code = mapflag; 153826049Sminshall return; 153926049Sminshall } 154026049Sminshall if (argc < 3) { 1541*26497Sminshall (void) strcat(line, " "); 154226049Sminshall printf("(mapout) "); 1543*26497Sminshall (void) gets(&line[strlen(line)]); 154426049Sminshall makeargv(); 154526049Sminshall argc = margc; 154626049Sminshall argv = margv; 154726049Sminshall } 154826049Sminshall if (argc < 3) { 154926049Sminshall printf("Usage: %s [mapin mapout]\n",argv[0]); 155026049Sminshall code = -1; 155126049Sminshall return; 155226049Sminshall } 155326049Sminshall mapflag = 1; 155426049Sminshall code = 1; 155526049Sminshall cp = index(altarg, ' '); 155626049Sminshall if (proxy) { 155726049Sminshall while(*++cp == ' '); 155826049Sminshall altarg = cp; 155926049Sminshall cp = index(altarg, ' '); 156026049Sminshall } 156126049Sminshall *cp = '\0'; 156226049Sminshall (void) strncpy(mapin, altarg, MAXPATHLEN - 1); 156326049Sminshall while (*++cp == ' '); 156426049Sminshall (void) strncpy(mapout, cp, MAXPATHLEN - 1); 156526049Sminshall } 156626049Sminshall 156726049Sminshall char * 156826049Sminshall domap(name) 156926049Sminshall char *name; 157026049Sminshall { 157126049Sminshall static char new[MAXPATHLEN]; 157226049Sminshall register char *cp1 = name, *cp2 = mapin; 157326049Sminshall char *tp[9], *te[9]; 157426049Sminshall int i, toks[9], toknum, match = 1; 157526049Sminshall 157626049Sminshall for (i=0; i < 9; ++i) { 157726049Sminshall toks[i] = 0; 157826049Sminshall } 157926049Sminshall while (match && *cp1 && *cp2) { 158026049Sminshall switch (*cp2) { 158126049Sminshall case '\\': 158226049Sminshall if (*++cp2 != *cp1) { 158326049Sminshall match = 0; 158426049Sminshall } 158526049Sminshall break; 158626049Sminshall case '$': 158726049Sminshall if (*(cp2+1) >= '1' && (*cp2+1) <= '9') { 158826049Sminshall if (*cp1 != *(++cp2+1)) { 158926049Sminshall toks[toknum = *cp2 - '1']++; 159026049Sminshall tp[toknum] = cp1; 159126049Sminshall while (*++cp1 && *(cp2+1) 159226049Sminshall != *cp1); 159326049Sminshall te[toknum] = cp1; 159426049Sminshall } 159526049Sminshall cp2++; 159626049Sminshall break; 159726049Sminshall } 159826049Sminshall /* intentional drop through */ 159926049Sminshall default: 160026049Sminshall if (*cp2 != *cp1) { 160126049Sminshall match = 0; 160226049Sminshall } 160326049Sminshall break; 160426049Sminshall } 160526049Sminshall if (*cp1) { 160626049Sminshall cp1++; 160726049Sminshall } 160826049Sminshall if (*cp2) { 160926049Sminshall cp2++; 161026049Sminshall } 161126049Sminshall } 161226049Sminshall cp1 = new; 161326049Sminshall *cp1 = '\0'; 161426049Sminshall cp2 = mapout; 161526049Sminshall while (*cp2) { 161626049Sminshall match = 0; 161726049Sminshall switch (*cp2) { 161826049Sminshall case '\\': 161926049Sminshall if (*(cp2 + 1)) { 162026049Sminshall *cp1++ = *++cp2; 162126049Sminshall } 162226049Sminshall break; 162326049Sminshall case '[': 162426049Sminshall LOOP: 162526049Sminshall if (*++cp2 == '$' && isdigit(*(cp2+1))) { 162626049Sminshall if (*++cp2 == '0') { 162726049Sminshall char *cp3 = name; 162826049Sminshall 162926049Sminshall while (*cp3) { 163026049Sminshall *cp1++ = *cp3++; 163126049Sminshall } 163226049Sminshall match = 1; 163326049Sminshall } 163426049Sminshall else if (toks[toknum = *cp2 - '1']) { 163526049Sminshall char *cp3 = tp[toknum]; 163626049Sminshall 163726049Sminshall while (cp3 != te[toknum]) { 163826049Sminshall *cp1++ = *cp3++; 163926049Sminshall } 164026049Sminshall match = 1; 164126049Sminshall } 164226049Sminshall } 164326049Sminshall else { 164426049Sminshall while (*cp2 && *cp2 != ',' && 164526049Sminshall *cp2 != ']') { 164626049Sminshall if (*cp2 == '\\') { 164726049Sminshall cp2++; 164826049Sminshall } 164926049Sminshall else if (*cp2 == '$' && 165026049Sminshall isdigit(*(cp2+1))) { 165126049Sminshall if (*++cp2 == '0') { 165226049Sminshall char *cp3 = name; 165326049Sminshall 165426049Sminshall while (*cp3) { 165526049Sminshall *cp1++ = *cp3++; 165626049Sminshall } 165726049Sminshall } 165826049Sminshall else if (toks[toknum = 165926049Sminshall *cp2 - '1']) { 166026049Sminshall char *cp3=tp[toknum]; 166126049Sminshall 166226049Sminshall while (cp3 != 166326049Sminshall te[toknum]) { 166426049Sminshall *cp1++ = *cp3++; 166526049Sminshall } 166626049Sminshall } 166726049Sminshall } 166826049Sminshall else if (*cp2) { 166926049Sminshall *cp1++ = *cp2++; 167026049Sminshall } 167126049Sminshall } 167226049Sminshall if (!*cp2) { 167326049Sminshall printf("nmap: unbalanced brackets\n"); 167426049Sminshall return(name); 167526049Sminshall } 167626049Sminshall match = 1; 167726049Sminshall cp2--; 167826049Sminshall } 167926049Sminshall if (match) { 168026049Sminshall while (*++cp2 && *cp2 != ']') { 168126049Sminshall if (*cp2 == '\\' && *(cp2 + 1)) { 168226049Sminshall cp2++; 168326049Sminshall } 168426049Sminshall } 168526049Sminshall if (!*cp2) { 168626049Sminshall printf("nmap: unbalanced brackets\n"); 168726049Sminshall return(name); 168826049Sminshall } 168926049Sminshall break; 169026049Sminshall } 169126049Sminshall switch (*++cp2) { 169226049Sminshall case ',': 169326049Sminshall goto LOOP; 169426049Sminshall case ']': 169526049Sminshall break; 169626049Sminshall default: 169726049Sminshall cp2--; 169826049Sminshall goto LOOP; 169926049Sminshall } 170026049Sminshall break; 170126049Sminshall case '$': 170226049Sminshall if (isdigit(*(cp2 + 1))) { 170326049Sminshall if (*++cp2 == '0') { 170426049Sminshall char *cp3 = name; 170526049Sminshall 170626049Sminshall while (*cp3) { 170726049Sminshall *cp1++ = *cp3++; 170826049Sminshall } 170926049Sminshall } 171026049Sminshall else if (toks[toknum = *cp2 - '1']) { 171126049Sminshall char *cp3 = tp[toknum]; 171226049Sminshall 171326049Sminshall while (cp3 != te[toknum]) { 171426049Sminshall *cp1++ = *cp3++; 171526049Sminshall } 171626049Sminshall } 171726049Sminshall break; 171826049Sminshall } 171926049Sminshall /* intentional drop through */ 172026049Sminshall default: 172126049Sminshall *cp1++ = *cp2; 172226049Sminshall break; 172326049Sminshall } 172426049Sminshall cp2++; 172526049Sminshall } 172626049Sminshall *cp1 = '\0'; 172726049Sminshall if (!*new) { 172826049Sminshall return(name); 172926049Sminshall } 173026049Sminshall return(new); 173126049Sminshall } 173226049Sminshall 173326049Sminshall setsunique() 173426049Sminshall { 173526049Sminshall sunique = !sunique; 173626049Sminshall printf("Store unique %s.\n", onoff(sunique)); 173726049Sminshall code = sunique; 173826049Sminshall } 173926049Sminshall 174026049Sminshall setrunique() 174126049Sminshall { 174226049Sminshall runique = !runique; 174326049Sminshall printf("Receive unique %s.\n", onoff(runique)); 174426049Sminshall code = runique; 174526049Sminshall } 174626049Sminshall 174726049Sminshall /* change directory to perent directory */ 174826049Sminshall cdup() 174926049Sminshall { 175026049Sminshall (void) command("CDUP"); 175126049Sminshall } 175226049Sminshall 175326049Sminshall macdef(argc, argv) 175426049Sminshall int argc; 175526049Sminshall char *argv[]; 175626049Sminshall { 175726049Sminshall char *tmp; 175826049Sminshall int c; 175926049Sminshall 176026049Sminshall if (macnum == 16) { 176126049Sminshall printf("Limit of 16 macros have already been defined\n"); 176226049Sminshall code = -1; 176326049Sminshall return; 176426049Sminshall } 176526049Sminshall if (argc < 2) { 1766*26497Sminshall (void) strcat(line, " "); 176726049Sminshall printf("(macro name) "); 1768*26497Sminshall (void) gets(&line[strlen(line)]); 176926049Sminshall makeargv(); 177026049Sminshall argc = margc; 177126049Sminshall argv = margv; 177226049Sminshall } 177326049Sminshall if (argc != 2) { 177426049Sminshall printf("Usage: %s macro_name\n",argv[0]); 177526049Sminshall code = -1; 177626049Sminshall return; 177726049Sminshall } 177826049Sminshall if (interactive) { 177926049Sminshall printf("Enter macro line by line, terminating it with a null line\n"); 178026049Sminshall } 1781*26497Sminshall (void) strncpy(macros[macnum].mac_name, argv[1], 8); 178226049Sminshall if (macnum == 0) { 178326049Sminshall macros[macnum].mac_start = macbuf; 178426049Sminshall } 178526049Sminshall else { 178626049Sminshall macros[macnum].mac_start = macros[macnum - 1].mac_end + 1; 178726049Sminshall } 178826049Sminshall tmp = macros[macnum].mac_start; 178926049Sminshall while (tmp != macbuf+4096) { 179026049Sminshall if ((c = getchar()) == EOF) { 179126049Sminshall printf("macdef:end of file encountered\n"); 179226049Sminshall code = -1; 179326049Sminshall return; 179426049Sminshall } 179526049Sminshall if ((*tmp = c) == '\n') { 179626049Sminshall if (tmp == macros[macnum].mac_start) { 179726049Sminshall macros[macnum++].mac_end = tmp; 179826049Sminshall code = 0; 179926049Sminshall return; 180026049Sminshall } 180126049Sminshall if (*(tmp-1) == '\0') { 180226049Sminshall macros[macnum++].mac_end = tmp - 1; 180326049Sminshall code = 0; 180426049Sminshall return; 180526049Sminshall } 180626049Sminshall *tmp = '\0'; 180726049Sminshall } 180826049Sminshall tmp++; 180926049Sminshall } 181026049Sminshall while (1) { 181126049Sminshall while ((c = getchar()) != '\n' && c != EOF); 181226049Sminshall if (c == EOF || getchar() == '\n') { 181326049Sminshall printf("Macro not defined - 4k buffer exceeded\n"); 181426049Sminshall code = -1; 181526049Sminshall return; 181626049Sminshall } 181726049Sminshall } 181826049Sminshall } 1819