121737Sdist /* 226049Sminshall * Copyright (c) 1985 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 1534901Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621737Sdist */ 1721737Sdist 1810294Ssam #ifndef lint 19*35658Sbostic static char sccsid[] = "@(#)cmds.c 5.9 (Berkeley) 09/21/88"; 2033737Sbostic #endif /* not lint */ 2110294Ssam 2210294Ssam /* 2310294Ssam * FTP User Program -- Command Routines. 2410294Ssam */ 2526049Sminshall #include "ftp_var.h" 2610294Ssam #include <sys/socket.h> 2710294Ssam 2812396Ssam #include <arpa/ftp.h> 2912396Ssam 3010294Ssam #include <signal.h> 3110294Ssam #include <stdio.h> 3210294Ssam #include <errno.h> 3310294Ssam #include <netdb.h> 3426049Sminshall #include <ctype.h> 3526497Sminshall #include <sys/wait.h> 3610294Ssam 3710294Ssam 3811353Ssam extern char *globerr; 3911353Ssam extern char **glob(); 4011756Ssam extern char *home; 4111353Ssam extern short gflag; 4211756Ssam extern char *remglob(); 4311756Ssam extern char *getenv(); 4411756Ssam extern char *index(); 4511756Ssam extern char *rindex(); 4626049Sminshall char *mname; 4726049Sminshall jmp_buf jabort; 4826049Sminshall char *dotrans(), *domap(); 4910294Ssam 5010294Ssam /* 5110294Ssam * Connect to peer server and 5210294Ssam * auto-login, if possible. 5310294Ssam */ 5410294Ssam setpeer(argc, argv) 5510294Ssam int argc; 5610294Ssam char *argv[]; 5710294Ssam { 5825903Skarels char *host, *hookup(); 5910294Ssam int port; 6010294Ssam 6110294Ssam if (connected) { 6226049Sminshall printf("Already connected to %s, use close first.\n", 6310294Ssam hostname); 6426049Sminshall code = -1; 6510294Ssam return; 6610294Ssam } 6710294Ssam if (argc < 2) { 6826497Sminshall (void) strcat(line, " "); 6910294Ssam printf("(to) "); 7026497Sminshall (void) gets(&line[strlen(line)]); 7110294Ssam makeargv(); 7210294Ssam argc = margc; 7310294Ssam argv = margv; 7410294Ssam } 7510294Ssam if (argc > 3) { 7610294Ssam printf("usage: %s host-name [port]\n", argv[0]); 7726049Sminshall code = -1; 7810294Ssam return; 7910294Ssam } 8010294Ssam port = sp->s_port; 8110294Ssam if (argc > 2) { 8211218Ssam port = atoi(argv[2]); 8310294Ssam if (port <= 0) { 8411218Ssam printf("%s: bad port number-- %s\n", argv[1], argv[2]); 8511218Ssam printf ("usage: %s host-name [port]\n", argv[0]); 8626049Sminshall code = -1; 8710294Ssam return; 8810294Ssam } 8910294Ssam port = htons(port); 9010294Ssam } 9110294Ssam host = hookup(argv[1], port); 9210294Ssam if (host) { 9310294Ssam connected = 1; 9410294Ssam if (autologin) 9526497Sminshall (void) login(argv[1]); 9610294Ssam } 9710294Ssam } 9810294Ssam 9910294Ssam struct types { 10010294Ssam char *t_name; 10110294Ssam char *t_mode; 10210294Ssam int t_type; 10311218Ssam char *t_arg; 10410294Ssam } types[] = { 10511218Ssam { "ascii", "A", TYPE_A, 0 }, 10611218Ssam { "binary", "I", TYPE_I, 0 }, 10711218Ssam { "image", "I", TYPE_I, 0 }, 10811218Ssam { "ebcdic", "E", TYPE_E, 0 }, 10911218Ssam { "tenex", "L", TYPE_L, bytename }, 11010294Ssam 0 11110294Ssam }; 11210294Ssam 11310294Ssam /* 11410294Ssam * Set transfer type. 11510294Ssam */ 11610294Ssam settype(argc, argv) 11710294Ssam char *argv[]; 11810294Ssam { 11910294Ssam register struct types *p; 12011218Ssam int comret; 12110294Ssam 12210294Ssam if (argc > 2) { 12310294Ssam char *sep; 12410294Ssam 12510294Ssam printf("usage: %s [", argv[0]); 12610294Ssam sep = " "; 12710294Ssam for (p = types; p->t_name; p++) { 12810294Ssam printf("%s%s", sep, p->t_name); 12910294Ssam if (*sep == ' ') 13010294Ssam sep = " | "; 13110294Ssam } 13210294Ssam printf(" ]\n"); 13326049Sminshall code = -1; 13410294Ssam return; 13510294Ssam } 13610294Ssam if (argc < 2) { 13710294Ssam printf("Using %s mode to transfer files.\n", typename); 13826049Sminshall code = 0; 13910294Ssam return; 14010294Ssam } 14110294Ssam for (p = types; p->t_name; p++) 14210294Ssam if (strcmp(argv[1], p->t_name) == 0) 14310294Ssam break; 14410294Ssam if (p->t_name == 0) { 14510294Ssam printf("%s: unknown mode\n", argv[1]); 14626049Sminshall code = -1; 14710294Ssam return; 14810294Ssam } 14911218Ssam if ((p->t_arg != NULL) && (*(p->t_arg) != '\0')) 15011218Ssam comret = command ("TYPE %s %s", p->t_mode, p->t_arg); 15111218Ssam else 15211218Ssam comret = command("TYPE %s", p->t_mode); 15311218Ssam if (comret == COMPLETE) { 15426497Sminshall (void) strcpy(typename, p->t_name); 15510294Ssam type = p->t_type; 15610294Ssam } 15710294Ssam } 15810294Ssam 15910294Ssam /* 16010294Ssam * Set binary transfer type. 16110294Ssam */ 16210294Ssam /*VARARGS*/ 16310294Ssam setbinary() 16410294Ssam { 16510294Ssam 16610294Ssam call(settype, "type", "binary", 0); 16710294Ssam } 16810294Ssam 16910294Ssam /* 17010294Ssam * Set ascii transfer type. 17110294Ssam */ 17210294Ssam /*VARARGS*/ 17310294Ssam setascii() 17410294Ssam { 17510294Ssam 17610294Ssam call(settype, "type", "ascii", 0); 17710294Ssam } 17810294Ssam 17910294Ssam /* 18010294Ssam * Set tenex transfer type. 18110294Ssam */ 18210294Ssam /*VARARGS*/ 18310294Ssam settenex() 18410294Ssam { 18510294Ssam 18610294Ssam call(settype, "type", "tenex", 0); 18710294Ssam } 18810294Ssam 18910294Ssam /* 19010294Ssam * Set ebcdic transfer type. 19110294Ssam */ 19210294Ssam /*VARARGS*/ 19310294Ssam setebcdic() 19410294Ssam { 19510294Ssam 19610294Ssam call(settype, "type", "ebcdic", 0); 19710294Ssam } 19810294Ssam 19910294Ssam /* 20010294Ssam * Set file transfer mode. 20110294Ssam */ 20226497Sminshall /*ARGSUSED*/ 20310294Ssam setmode(argc, argv) 20410294Ssam char *argv[]; 20510294Ssam { 20610294Ssam 20710294Ssam printf("We only support %s mode, sorry.\n", modename); 20826049Sminshall code = -1; 20910294Ssam } 21010294Ssam 21110294Ssam /* 21210294Ssam * Set file transfer format. 21310294Ssam */ 21426497Sminshall /*ARGSUSED*/ 21510294Ssam setform(argc, argv) 21610294Ssam char *argv[]; 21710294Ssam { 21810294Ssam 21910294Ssam printf("We only support %s format, sorry.\n", formname); 22026049Sminshall code = -1; 22110294Ssam } 22210294Ssam 22310294Ssam /* 22410294Ssam * Set file transfer structure. 22510294Ssam */ 22626497Sminshall /*ARGSUSED*/ 22710294Ssam setstruct(argc, argv) 22810294Ssam char *argv[]; 22910294Ssam { 23010294Ssam 23110294Ssam printf("We only support %s structure, sorry.\n", structname); 23226049Sminshall code = -1; 23310294Ssam } 23410294Ssam 23518286Sralph /* 23618286Sralph * Send a single file. 23718286Sralph */ 23810294Ssam put(argc, argv) 23911756Ssam int argc; 24010294Ssam char *argv[]; 24110294Ssam { 24211650Ssam char *cmd; 24326049Sminshall int loc = 0; 24425908Smckusick char *oldargv1; 24511650Ssam 24626049Sminshall if (argc == 2) { 24726049Sminshall argc++; 24826049Sminshall argv[2] = argv[1]; 24926049Sminshall loc++; 25026049Sminshall } 25110294Ssam if (argc < 2) { 25226497Sminshall (void) strcat(line, " "); 25310294Ssam printf("(local-file) "); 25426497Sminshall (void) gets(&line[strlen(line)]); 25510294Ssam makeargv(); 25610294Ssam argc = margc; 25710294Ssam argv = margv; 25810294Ssam } 25910294Ssam if (argc < 2) { 26010294Ssam usage: 26126049Sminshall printf("usage:%s local-file remote-file\n", argv[0]); 26226049Sminshall code = -1; 26310294Ssam return; 26410294Ssam } 26510294Ssam if (argc < 3) { 26626497Sminshall (void) strcat(line, " "); 26710294Ssam printf("(remote-file) "); 26826497Sminshall (void) gets(&line[strlen(line)]); 26910294Ssam makeargv(); 27010294Ssam argc = margc; 27110294Ssam argv = margv; 27210294Ssam } 27310294Ssam if (argc < 3) 27410294Ssam goto usage; 27525908Smckusick oldargv1 = argv[1]; 27626049Sminshall if (!globulize(&argv[1])) { 27726049Sminshall code = -1; 27811353Ssam return; 27926049Sminshall } 28025908Smckusick /* 28125908Smckusick * If "globulize" modifies argv[1], and argv[2] is a copy of 28225908Smckusick * the old argv[1], make it a copy of the new argv[1]. 28325908Smckusick */ 28426049Sminshall if (argv[1] != oldargv1 && argv[2] == oldargv1) { 28525908Smckusick argv[2] = argv[1]; 28626049Sminshall } 28726049Sminshall cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR"); 28826049Sminshall if (loc && ntflag) { 28926049Sminshall argv[2] = dotrans(argv[2]); 29026049Sminshall } 29126049Sminshall if (loc && mapflag) { 29226049Sminshall argv[2] = domap(argv[2]); 29326049Sminshall } 29411650Ssam sendrequest(cmd, argv[1], argv[2]); 29510294Ssam } 29610294Ssam 29710294Ssam /* 29811756Ssam * Send multiple files. 29910294Ssam */ 30011353Ssam mput(argc, argv) 30111353Ssam char *argv[]; 30211353Ssam { 30313212Ssam register int i; 30426049Sminshall int ointer, (*oldintr)(), mabort(); 30526049Sminshall extern jmp_buf jabort; 30626049Sminshall char *tp; 30711353Ssam 30811650Ssam if (argc < 2) { 30926497Sminshall (void) strcat(line, " "); 31011650Ssam printf("(local-files) "); 31126497Sminshall (void) gets(&line[strlen(line)]); 31211650Ssam makeargv(); 31311650Ssam argc = margc; 31411650Ssam argv = margv; 31511353Ssam } 31611353Ssam if (argc < 2) { 31726049Sminshall printf("usage:%s local-files\n", argv[0]); 31826049Sminshall code = -1; 31911353Ssam return; 32011353Ssam } 32126049Sminshall mname = argv[0]; 32226049Sminshall mflag = 1; 32326049Sminshall oldintr = signal(SIGINT, mabort); 32426049Sminshall (void) setjmp(jabort); 32526049Sminshall if (proxy) { 32626049Sminshall char *cp, *tp2, tmpbuf[MAXPATHLEN]; 32726049Sminshall 32826497Sminshall while ((cp = remglob(argv,0)) != NULL) { 32926049Sminshall if (*cp == 0) { 33026049Sminshall mflag = 0; 33126049Sminshall continue; 33226049Sminshall } 33326049Sminshall if (mflag && confirm(argv[0], cp)) { 33426049Sminshall tp = cp; 33526049Sminshall if (mcase) { 33626049Sminshall while (*tp && !islower(*tp)) { 33726049Sminshall tp++; 33826049Sminshall } 33926049Sminshall if (!*tp) { 34026049Sminshall tp = cp; 34126049Sminshall tp2 = tmpbuf; 34226049Sminshall while ((*tp2 = *tp) != NULL) { 34326049Sminshall if (isupper(*tp2)) { 34426049Sminshall *tp2 = 'a' + *tp2 - 'A'; 34526049Sminshall } 34626049Sminshall tp++; 34726049Sminshall tp2++; 34826049Sminshall } 34926049Sminshall } 35026049Sminshall tp = tmpbuf; 35126049Sminshall } 35226049Sminshall if (ntflag) { 35326049Sminshall tp = dotrans(tp); 35426049Sminshall } 35526049Sminshall if (mapflag) { 35626049Sminshall tp = domap(tp); 35726049Sminshall } 35826049Sminshall sendrequest((sunique) ? "STOU" : "STOR", cp,tp); 35926049Sminshall if (!mflag && fromatty) { 36026049Sminshall ointer = interactive; 36126049Sminshall interactive = 1; 36226049Sminshall if (confirm("Continue with","mput")) { 36326049Sminshall mflag++; 36426049Sminshall } 36526049Sminshall interactive = ointer; 36626049Sminshall } 36726049Sminshall } 36826049Sminshall } 36926049Sminshall (void) signal(SIGINT, oldintr); 37026049Sminshall mflag = 0; 37126049Sminshall return; 37226049Sminshall } 37313212Ssam for (i = 1; i < argc; i++) { 37413212Ssam register char **cpp, **gargs; 37513212Ssam 37613212Ssam if (!doglob) { 37726049Sminshall if (mflag && confirm(argv[0], argv[i])) { 37826049Sminshall tp = (ntflag) ? dotrans(argv[i]) : argv[i]; 37926049Sminshall tp = (mapflag) ? domap(tp) : tp; 38026049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 38126049Sminshall argv[i], tp); 38226049Sminshall if (!mflag && fromatty) { 38326049Sminshall ointer = interactive; 38426049Sminshall interactive = 1; 38526049Sminshall if (confirm("Continue with","mput")) { 38626049Sminshall mflag++; 38726049Sminshall } 38826049Sminshall interactive = ointer; 38926049Sminshall } 39026049Sminshall } 39113212Ssam continue; 39213212Ssam } 39313212Ssam gargs = glob(argv[i]); 39411650Ssam if (globerr != NULL) { 39511650Ssam printf("%s\n", globerr); 39611650Ssam if (gargs) 39711650Ssam blkfree(gargs); 39813212Ssam continue; 39911353Ssam } 40026049Sminshall for (cpp = gargs; cpp && *cpp != NULL; cpp++) { 40126049Sminshall if (mflag && confirm(argv[0], *cpp)) { 40226049Sminshall tp = (ntflag) ? dotrans(*cpp) : *cpp; 40326049Sminshall tp = (mapflag) ? domap(tp) : tp; 40426049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 40526049Sminshall *cpp, tp); 40626049Sminshall if (!mflag && fromatty) { 40726049Sminshall ointer = interactive; 40826049Sminshall interactive = 1; 40926049Sminshall if (confirm("Continue with","mput")) { 41026049Sminshall mflag++; 41126049Sminshall } 41226049Sminshall interactive = ointer; 41326049Sminshall } 41426049Sminshall } 41526049Sminshall } 41613212Ssam if (gargs != NULL) 41713212Ssam blkfree(gargs); 41811353Ssam } 41926049Sminshall (void) signal(SIGINT, oldintr); 42026049Sminshall mflag = 0; 42111353Ssam } 42211353Ssam 42311353Ssam /* 42411353Ssam * Receive one file. 42511353Ssam */ 42610294Ssam get(argc, argv) 42710294Ssam char *argv[]; 42810294Ssam { 42926049Sminshall int loc = 0; 43010294Ssam 43126049Sminshall if (argc == 2) { 43226049Sminshall argc++; 43326049Sminshall argv[2] = argv[1]; 43426049Sminshall loc++; 43526049Sminshall } 43610294Ssam if (argc < 2) { 43726497Sminshall (void) strcat(line, " "); 43810294Ssam printf("(remote-file) "); 43926497Sminshall (void) gets(&line[strlen(line)]); 44010294Ssam makeargv(); 44110294Ssam argc = margc; 44210294Ssam argv = margv; 44310294Ssam } 44410294Ssam if (argc < 2) { 44510294Ssam usage: 44626049Sminshall printf("usage: %s remote-file [ local-file ]\n", argv[0]); 44726049Sminshall code = -1; 44810294Ssam return; 44910294Ssam } 45010294Ssam if (argc < 3) { 45126497Sminshall (void) strcat(line, " "); 45210294Ssam printf("(local-file) "); 45326497Sminshall (void) gets(&line[strlen(line)]); 45410294Ssam makeargv(); 45510294Ssam argc = margc; 45610294Ssam argv = margv; 45710294Ssam } 45810294Ssam if (argc < 3) 45910294Ssam goto usage; 46026049Sminshall if (!globulize(&argv[2])) { 46126049Sminshall code = -1; 46211353Ssam return; 46326049Sminshall } 46426049Sminshall if (loc && mcase) { 46526049Sminshall char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN]; 46626049Sminshall 46726049Sminshall while (*tp && !islower(*tp)) { 46826049Sminshall tp++; 46926049Sminshall } 47026049Sminshall if (!*tp) { 47126049Sminshall tp = argv[2]; 47226049Sminshall tp2 = tmpbuf; 47326049Sminshall while ((*tp2 = *tp) != NULL) { 47426049Sminshall if (isupper(*tp2)) { 47526049Sminshall *tp2 = 'a' + *tp2 - 'A'; 47626049Sminshall } 47726049Sminshall tp++; 47826049Sminshall tp2++; 47926049Sminshall } 48026049Sminshall argv[2] = tmpbuf; 48126049Sminshall } 48226049Sminshall } 48326049Sminshall if (loc && ntflag) { 48426049Sminshall argv[2] = dotrans(argv[2]); 48526049Sminshall } 48626049Sminshall if (loc && mapflag) { 48726049Sminshall argv[2] = domap(argv[2]); 48826049Sminshall } 48911650Ssam recvrequest("RETR", argv[2], argv[1], "w"); 49010294Ssam } 49110294Ssam 49226049Sminshall mabort() 49326049Sminshall { 49426049Sminshall int ointer; 49526049Sminshall extern jmp_buf jabort; 49626049Sminshall 49726049Sminshall printf("\n"); 49826049Sminshall (void) fflush(stdout); 49926049Sminshall if (mflag && fromatty) { 50026049Sminshall ointer = interactive; 50126049Sminshall interactive = 1; 50226049Sminshall if (confirm("Continue with", mname)) { 50326049Sminshall interactive = ointer; 50426049Sminshall longjmp(jabort,0); 50526049Sminshall } 50626049Sminshall interactive = ointer; 50726049Sminshall } 50826049Sminshall mflag = 0; 50926049Sminshall longjmp(jabort,0); 51026049Sminshall } 51126049Sminshall 51211353Ssam /* 51311353Ssam * Get multiple files. 51411353Ssam */ 51511353Ssam mget(argc, argv) 51611353Ssam char *argv[]; 51711353Ssam { 51826049Sminshall char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN]; 51926049Sminshall int ointer, (*oldintr)(), mabort(); 52026049Sminshall extern jmp_buf jabort; 52111353Ssam 52211353Ssam if (argc < 2) { 52326497Sminshall (void) strcat(line, " "); 52411756Ssam printf("(remote-files) "); 52526497Sminshall (void) gets(&line[strlen(line)]); 52611353Ssam makeargv(); 52711353Ssam argc = margc; 52811353Ssam argv = margv; 52911353Ssam } 53011353Ssam if (argc < 2) { 53126049Sminshall printf("usage:%s remote-files\n", argv[0]); 53226049Sminshall code = -1; 53311353Ssam return; 53411353Ssam } 53526049Sminshall mname = argv[0]; 53626049Sminshall mflag = 1; 53726049Sminshall oldintr = signal(SIGINT,mabort); 53826049Sminshall (void) setjmp(jabort); 53926497Sminshall while ((cp = remglob(argv,proxy)) != NULL) { 54026049Sminshall if (*cp == '\0') { 54126049Sminshall mflag = 0; 54226049Sminshall continue; 54326049Sminshall } 54426049Sminshall if (mflag && confirm(argv[0], cp)) { 54526049Sminshall tp = cp; 54626049Sminshall if (mcase) { 54726049Sminshall while (*tp && !islower(*tp)) { 54826049Sminshall tp++; 54926049Sminshall } 55026049Sminshall if (!*tp) { 55126049Sminshall tp = cp; 55226049Sminshall tp2 = tmpbuf; 55326049Sminshall while ((*tp2 = *tp) != NULL) { 55426049Sminshall if (isupper(*tp2)) { 55526049Sminshall *tp2 = 'a' + *tp2 - 'A'; 55626049Sminshall } 55726049Sminshall tp++; 55826049Sminshall tp2++; 55926049Sminshall } 56026049Sminshall } 56126049Sminshall tp = tmpbuf; 56226049Sminshall } 56326049Sminshall if (ntflag) { 56426049Sminshall tp = dotrans(tp); 56526049Sminshall } 56626049Sminshall if (mapflag) { 56726049Sminshall tp = domap(tp); 56826049Sminshall } 56926049Sminshall recvrequest("RETR", tp, cp, "w"); 57026049Sminshall if (!mflag && fromatty) { 57126049Sminshall ointer = interactive; 57226049Sminshall interactive = 1; 57326049Sminshall if (confirm("Continue with","mget")) { 57426049Sminshall mflag++; 57526049Sminshall } 57626049Sminshall interactive = ointer; 57726049Sminshall } 57826049Sminshall } 57926049Sminshall } 58026049Sminshall (void) signal(SIGINT,oldintr); 58126049Sminshall mflag = 0; 58211650Ssam } 58311650Ssam 58411650Ssam char * 58526497Sminshall remglob(argv,doswitch) 58611650Ssam char *argv[]; 58726497Sminshall int doswitch; 58811650Ssam { 58911756Ssam char temp[16]; 59011650Ssam static char buf[MAXPATHLEN]; 59111650Ssam static FILE *ftemp = NULL; 59211650Ssam static char **args; 59313212Ssam int oldverbose, oldhash; 59411756Ssam char *cp, *mode; 59511650Ssam 59626049Sminshall if (!mflag) { 59726049Sminshall if (!doglob) { 59826049Sminshall args = NULL; 59926049Sminshall } 60026049Sminshall else { 60126049Sminshall if (ftemp) { 60226497Sminshall (void) fclose(ftemp); 60326049Sminshall ftemp = NULL; 60426049Sminshall } 60526049Sminshall } 60626049Sminshall return(NULL); 60726049Sminshall } 60811650Ssam if (!doglob) { 60911756Ssam if (args == NULL) 61011650Ssam args = argv; 61111650Ssam if ((cp = *++args) == NULL) 61211650Ssam args = NULL; 61311650Ssam return (cp); 61411353Ssam } 61511650Ssam if (ftemp == NULL) { 61626497Sminshall (void) strcpy(temp, "/tmp/ftpXXXXXX"); 61726497Sminshall (void) mktemp(temp); 61811650Ssam oldverbose = verbose, verbose = 0; 61913212Ssam oldhash = hash, hash = 0; 62026049Sminshall if (doswitch) { 62126049Sminshall pswitch(!proxy); 62226049Sminshall } 62311756Ssam for (mode = "w"; *++argv != NULL; mode = "a") 62411756Ssam recvrequest ("NLST", temp, *argv, mode); 62526049Sminshall if (doswitch) { 62626049Sminshall pswitch(!proxy); 62726049Sminshall } 62813212Ssam verbose = oldverbose; hash = oldhash; 62911650Ssam ftemp = fopen(temp, "r"); 63026497Sminshall (void) unlink(temp); 63111650Ssam if (ftemp == NULL) { 63211650Ssam printf("can't find list of remote files, oops\n"); 63311756Ssam return (NULL); 63411353Ssam } 63511353Ssam } 63611650Ssam if (fgets(buf, sizeof (buf), ftemp) == NULL) { 63726497Sminshall (void) fclose(ftemp), ftemp = NULL; 63811650Ssam return (NULL); 63911353Ssam } 64011650Ssam if ((cp = index(buf, '\n')) != NULL) 64111650Ssam *cp = '\0'; 64211650Ssam return (buf); 64311353Ssam } 64411353Ssam 64510294Ssam char * 64610294Ssam onoff(bool) 64710294Ssam int bool; 64810294Ssam { 64910294Ssam 65010294Ssam return (bool ? "on" : "off"); 65110294Ssam } 65210294Ssam 65310294Ssam /* 65410294Ssam * Show status. 65510294Ssam */ 65626497Sminshall /*ARGSUSED*/ 65710294Ssam status(argc, argv) 65810294Ssam char *argv[]; 65910294Ssam { 66026049Sminshall int i; 66110294Ssam 66210294Ssam if (connected) 66310294Ssam printf("Connected to %s.\n", hostname); 66410294Ssam else 66510294Ssam printf("Not connected.\n"); 66626049Sminshall if (!proxy) { 66726049Sminshall pswitch(1); 66826049Sminshall if (connected) { 66926049Sminshall printf("Connected for proxy commands to %s.\n", hostname); 67026049Sminshall } 67126049Sminshall else { 67226049Sminshall printf("No proxy connection.\n"); 67326049Sminshall } 67426049Sminshall pswitch(0); 67526049Sminshall } 67610294Ssam printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n", 67710294Ssam modename, typename, formname, structname); 67811353Ssam printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 67911353Ssam onoff(verbose), onoff(bell), onoff(interactive), 68011353Ssam onoff(doglob)); 68126049Sminshall printf("Store unique: %s; Receive unique: %s\n", onoff(sunique), 68226049Sminshall onoff(runique)); 68326049Sminshall printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag)); 68426049Sminshall if (ntflag) { 68526049Sminshall printf("Ntrans: (in) %s (out) %s\n", ntin,ntout); 68626049Sminshall } 68726049Sminshall else { 68826049Sminshall printf("Ntrans: off\n"); 68926049Sminshall } 69026049Sminshall if (mapflag) { 69126049Sminshall printf("Nmap: (in) %s (out) %s\n", mapin, mapout); 69226049Sminshall } 69326049Sminshall else { 69426049Sminshall printf("Nmap: off\n"); 69526049Sminshall } 69614143Ssam printf("Hash mark printing: %s; Use of PORT cmds: %s\n", 69714143Ssam onoff(hash), onoff(sendport)); 69826049Sminshall if (macnum > 0) { 69926049Sminshall printf("Macros:\n"); 70026049Sminshall for (i=0; i<macnum; i++) { 70126049Sminshall printf("\t%s\n",macros[i].mac_name); 70226049Sminshall } 70326049Sminshall } 70426049Sminshall code = 0; 70510294Ssam } 70610294Ssam 70710294Ssam /* 70810294Ssam * Set beep on cmd completed mode. 70910294Ssam */ 71010294Ssam /*VARARGS*/ 71110294Ssam setbell() 71210294Ssam { 71310294Ssam 71410294Ssam bell = !bell; 71510294Ssam printf("Bell mode %s.\n", onoff(bell)); 71626049Sminshall code = bell; 71710294Ssam } 71810294Ssam 71910294Ssam /* 72010294Ssam * Turn on packet tracing. 72110294Ssam */ 72210294Ssam /*VARARGS*/ 72310294Ssam settrace() 72410294Ssam { 72510294Ssam 72610294Ssam trace = !trace; 72710294Ssam printf("Packet tracing %s.\n", onoff(trace)); 72826049Sminshall code = trace; 72910294Ssam } 73010294Ssam 73110294Ssam /* 73211650Ssam * Toggle hash mark printing during transfers. 73311650Ssam */ 73411650Ssam /*VARARGS*/ 73511650Ssam sethash() 73611650Ssam { 73711650Ssam 73811650Ssam hash = !hash; 73911650Ssam printf("Hash mark printing %s", onoff(hash)); 74026049Sminshall code = hash; 74111650Ssam if (hash) 74211650Ssam printf(" (%d bytes/hash mark)", BUFSIZ); 74311650Ssam printf(".\n"); 74411650Ssam } 74511650Ssam 74611650Ssam /* 74710294Ssam * Turn on printing of server echo's. 74810294Ssam */ 74910294Ssam /*VARARGS*/ 75010294Ssam setverbose() 75110294Ssam { 75210294Ssam 75310294Ssam verbose = !verbose; 75410294Ssam printf("Verbose mode %s.\n", onoff(verbose)); 75526049Sminshall code = verbose; 75610294Ssam } 75710294Ssam 75810294Ssam /* 75911650Ssam * Toggle PORT cmd use before each data connection. 76011650Ssam */ 76111650Ssam /*VARARGS*/ 76211650Ssam setport() 76311650Ssam { 76411650Ssam 76511650Ssam sendport = !sendport; 76611650Ssam printf("Use of PORT cmds %s.\n", onoff(sendport)); 76726049Sminshall code = sendport; 76811650Ssam } 76911650Ssam 77011650Ssam /* 77110294Ssam * Turn on interactive prompting 77210294Ssam * during mget, mput, and mdelete. 77310294Ssam */ 77410294Ssam /*VARARGS*/ 77510294Ssam setprompt() 77610294Ssam { 77710294Ssam 77810294Ssam interactive = !interactive; 77910294Ssam printf("Interactive mode %s.\n", onoff(interactive)); 78026049Sminshall code = interactive; 78110294Ssam } 78210294Ssam 78310294Ssam /* 78411353Ssam * Toggle metacharacter interpretation 78511353Ssam * on local file names. 78611353Ssam */ 78711353Ssam /*VARARGS*/ 78811353Ssam setglob() 78911353Ssam { 79011353Ssam 79111353Ssam doglob = !doglob; 79211353Ssam printf("Globbing %s.\n", onoff(doglob)); 79326049Sminshall code = doglob; 79411353Ssam } 79511353Ssam 79611353Ssam /* 79710294Ssam * Set debugging mode on/off and/or 79810294Ssam * set level of debugging. 79910294Ssam */ 80011756Ssam /*VARARGS*/ 80110294Ssam setdebug(argc, argv) 80210294Ssam char *argv[]; 80310294Ssam { 80410294Ssam int val; 80510294Ssam 80610294Ssam if (argc > 1) { 80710294Ssam val = atoi(argv[1]); 80810294Ssam if (val < 0) { 80910294Ssam printf("%s: bad debugging value.\n", argv[1]); 81026049Sminshall code = -1; 81110294Ssam return; 81210294Ssam } 81310294Ssam } else 81410294Ssam val = !debug; 81510294Ssam debug = val; 81610294Ssam if (debug) 81710294Ssam options |= SO_DEBUG; 81810294Ssam else 81910294Ssam options &= ~SO_DEBUG; 82010294Ssam printf("Debugging %s (debug=%d).\n", onoff(debug), debug); 82126049Sminshall code = debug > 0; 82210294Ssam } 82310294Ssam 82410294Ssam /* 82510294Ssam * Set current working directory 82610294Ssam * on remote machine. 82710294Ssam */ 82810294Ssam cd(argc, argv) 82910294Ssam char *argv[]; 83010294Ssam { 83110294Ssam 83210294Ssam if (argc < 2) { 83326497Sminshall (void) strcat(line, " "); 83410294Ssam printf("(remote-directory) "); 83526497Sminshall (void) gets(&line[strlen(line)]); 83610294Ssam makeargv(); 83710294Ssam argc = margc; 83810294Ssam argv = margv; 83910294Ssam } 84010294Ssam if (argc < 2) { 84126049Sminshall printf("usage:%s remote-directory\n", argv[0]); 84226049Sminshall code = -1; 84310294Ssam return; 84410294Ssam } 84510294Ssam (void) command("CWD %s", argv[1]); 84610294Ssam } 84710294Ssam 84810294Ssam /* 84910294Ssam * Set current working directory 85010294Ssam * on local machine. 85110294Ssam */ 85210294Ssam lcd(argc, argv) 85310294Ssam char *argv[]; 85410294Ssam { 85511353Ssam char buf[MAXPATHLEN]; 85610294Ssam 85711353Ssam if (argc < 2) 85811353Ssam argc++, argv[1] = home; 85910294Ssam if (argc != 2) { 86026049Sminshall printf("usage:%s local-directory\n", argv[0]); 86126049Sminshall code = -1; 86210294Ssam return; 86310294Ssam } 86426049Sminshall if (!globulize(&argv[1])) { 86526049Sminshall code = -1; 86611353Ssam return; 86726049Sminshall } 86811353Ssam if (chdir(argv[1]) < 0) { 86910294Ssam perror(argv[1]); 87026049Sminshall code = -1; 87111353Ssam return; 87211353Ssam } 87311353Ssam printf("Local directory now %s\n", getwd(buf)); 87426049Sminshall code = 0; 87510294Ssam } 87610294Ssam 87710294Ssam /* 87810294Ssam * Delete a single file. 87910294Ssam */ 88010294Ssam delete(argc, argv) 88110294Ssam char *argv[]; 88210294Ssam { 88310294Ssam 88410294Ssam if (argc < 2) { 88526497Sminshall (void) strcat(line, " "); 88610294Ssam printf("(remote-file) "); 88726497Sminshall (void) gets(&line[strlen(line)]); 88810294Ssam makeargv(); 88910294Ssam argc = margc; 89010294Ssam argv = margv; 89110294Ssam } 89210294Ssam if (argc < 2) { 89326049Sminshall printf("usage:%s remote-file\n", argv[0]); 89426049Sminshall code = -1; 89510294Ssam return; 89610294Ssam } 89710294Ssam (void) command("DELE %s", argv[1]); 89810294Ssam } 89910294Ssam 90010294Ssam /* 90111650Ssam * Delete multiple files. 90211650Ssam */ 90311650Ssam mdelete(argc, argv) 90411650Ssam char *argv[]; 90511650Ssam { 90611650Ssam char *cp; 90726049Sminshall int ointer, (*oldintr)(), mabort(); 90826049Sminshall extern jmp_buf jabort; 90911650Ssam 91011650Ssam if (argc < 2) { 91126497Sminshall (void) strcat(line, " "); 91211650Ssam printf("(remote-files) "); 91326497Sminshall (void) gets(&line[strlen(line)]); 91411650Ssam makeargv(); 91511650Ssam argc = margc; 91611650Ssam argv = margv; 91711650Ssam } 91811650Ssam if (argc < 2) { 91926049Sminshall printf("usage:%s remote-files\n", argv[0]); 92026049Sminshall code = -1; 92111650Ssam return; 92211650Ssam } 92326049Sminshall mname = argv[0]; 92426049Sminshall mflag = 1; 92526049Sminshall oldintr = signal(SIGINT, mabort); 92626049Sminshall (void) setjmp(jabort); 92726497Sminshall while ((cp = remglob(argv,0)) != NULL) { 92826049Sminshall if (*cp == '\0') { 92926049Sminshall mflag = 0; 93026049Sminshall continue; 93126049Sminshall } 93226049Sminshall if (mflag && confirm(argv[0], cp)) { 93311650Ssam (void) command("DELE %s", cp); 93426049Sminshall if (!mflag && fromatty) { 93526049Sminshall ointer = interactive; 93626049Sminshall interactive = 1; 93726049Sminshall if (confirm("Continue with", "mdelete")) { 93826049Sminshall mflag++; 93926049Sminshall } 94026049Sminshall interactive = ointer; 94126049Sminshall } 94226049Sminshall } 94326049Sminshall } 94426049Sminshall (void) signal(SIGINT, oldintr); 94526049Sminshall mflag = 0; 94611650Ssam } 94711756Ssam 94811650Ssam /* 94910294Ssam * Rename a remote file. 95010294Ssam */ 95110294Ssam renamefile(argc, argv) 95210294Ssam char *argv[]; 95310294Ssam { 95410294Ssam 95510294Ssam if (argc < 2) { 95626497Sminshall (void) strcat(line, " "); 95710294Ssam printf("(from-name) "); 95826497Sminshall (void) gets(&line[strlen(line)]); 95910294Ssam makeargv(); 96010294Ssam argc = margc; 96110294Ssam argv = margv; 96210294Ssam } 96310294Ssam if (argc < 2) { 96410294Ssam usage: 96510294Ssam printf("%s from-name to-name\n", argv[0]); 96626049Sminshall code = -1; 96710294Ssam return; 96810294Ssam } 96910294Ssam if (argc < 3) { 97026497Sminshall (void) strcat(line, " "); 97110294Ssam printf("(to-name) "); 97226497Sminshall (void) gets(&line[strlen(line)]); 97310294Ssam makeargv(); 97410294Ssam argc = margc; 97510294Ssam argv = margv; 97610294Ssam } 97710294Ssam if (argc < 3) 97810294Ssam goto usage; 97910294Ssam if (command("RNFR %s", argv[1]) == CONTINUE) 98010294Ssam (void) command("RNTO %s", argv[2]); 98110294Ssam } 98210294Ssam 98310294Ssam /* 98410294Ssam * Get a directory listing 98510294Ssam * of remote files. 98610294Ssam */ 98710294Ssam ls(argc, argv) 98810294Ssam char *argv[]; 98910294Ssam { 99011756Ssam char *cmd; 99110294Ssam 99210294Ssam if (argc < 2) 99310294Ssam argc++, argv[1] = NULL; 99410294Ssam if (argc < 3) 99510294Ssam argc++, argv[2] = "-"; 99611756Ssam if (argc > 3) { 99711756Ssam printf("usage: %s remote-directory local-file\n", argv[0]); 99826049Sminshall code = -1; 99911756Ssam return; 100011756Ssam } 100110294Ssam cmd = argv[0][0] == 'l' ? "NLST" : "LIST"; 100226049Sminshall if (strcmp(argv[2], "-") && !globulize(&argv[2])) { 100326049Sminshall code = -1; 100411353Ssam return; 100526049Sminshall } 100632344Scsvsj if (strcmp(argv[2], "-") && *argv[2] != '|') 100732344Scsvsj if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) { 100832344Scsvsj code = -1; 100932344Scsvsj return; 101032344Scsvsj } 101111756Ssam recvrequest(cmd, argv[2], argv[1], "w"); 101210294Ssam } 101310294Ssam 101410294Ssam /* 101511756Ssam * Get a directory listing 101611756Ssam * of multiple remote files. 101711756Ssam */ 101811756Ssam mls(argc, argv) 101911756Ssam char *argv[]; 102011756Ssam { 102126049Sminshall char *cmd, mode[1], *dest; 102226049Sminshall int ointer, i, (*oldintr)(), mabort(); 102326049Sminshall extern jmp_buf jabort; 102411756Ssam 102513212Ssam if (argc < 2) { 102626497Sminshall (void) strcat(line, " "); 102713212Ssam printf("(remote-files) "); 102826497Sminshall (void) gets(&line[strlen(line)]); 102913212Ssam makeargv(); 103013212Ssam argc = margc; 103113212Ssam argv = margv; 103213212Ssam } 103313212Ssam if (argc < 3) { 103426497Sminshall (void) strcat(line, " "); 103513212Ssam printf("(local-file) "); 103626497Sminshall (void) gets(&line[strlen(line)]); 103713212Ssam makeargv(); 103813212Ssam argc = margc; 103913212Ssam argv = margv; 104013212Ssam } 104113212Ssam if (argc < 3) { 104226049Sminshall printf("usage:%s remote-files local-file\n", argv[0]); 104326049Sminshall code = -1; 104413212Ssam return; 104513212Ssam } 104613212Ssam dest = argv[argc - 1]; 104713212Ssam argv[argc - 1] = NULL; 104826049Sminshall if (strcmp(dest, "-") && *dest != '|') 104926049Sminshall if (!globulize(&dest) || !confirm("output to local-file:", dest)) { 105026049Sminshall code = -1; 105113212Ssam return; 105226049Sminshall } 105311756Ssam cmd = argv[0][1] == 'l' ? "NLST" : "LIST"; 105426049Sminshall mname = argv[0]; 105526049Sminshall mflag = 1; 105626049Sminshall oldintr = signal(SIGINT, mabort); 105726049Sminshall (void) setjmp(jabort); 105826049Sminshall for (i = 1; mflag && i < argc-1; ++i) { 105926049Sminshall *mode = (i == 1) ? 'w' : 'a'; 106026049Sminshall recvrequest(cmd, dest, argv[i], mode); 106126049Sminshall if (!mflag && fromatty) { 106226049Sminshall ointer = interactive; 106326049Sminshall interactive = 1; 106426049Sminshall if (confirm("Continue with", argv[0])) { 106526049Sminshall mflag ++; 106626049Sminshall } 106726049Sminshall interactive = ointer; 106826049Sminshall } 106926049Sminshall } 107026049Sminshall (void) signal(SIGINT, oldintr); 107126049Sminshall mflag = 0; 107211756Ssam } 107311756Ssam 107411756Ssam /* 107510294Ssam * Do a shell escape 107610294Ssam */ 107726497Sminshall /*ARGSUSED*/ 107810294Ssam shell(argc, argv) 107910294Ssam char *argv[]; 108010294Ssam { 108126497Sminshall int pid, (*old1)(), (*old2)(); 108226049Sminshall char shellnam[40], *shell, *namep; 108326497Sminshall union wait status; 108410294Ssam 108511756Ssam old1 = signal (SIGINT, SIG_IGN); 108611756Ssam old2 = signal (SIGQUIT, SIG_IGN); 108711756Ssam if ((pid = fork()) == 0) { 108811756Ssam for (pid = 3; pid < 20; pid++) 108926497Sminshall (void) close(pid); 109026497Sminshall (void) signal(SIGINT, SIG_DFL); 109126497Sminshall (void) signal(SIGQUIT, SIG_DFL); 109225908Smckusick shell = getenv("SHELL"); 109325908Smckusick if (shell == NULL) 109425908Smckusick shell = "/bin/sh"; 109525908Smckusick namep = rindex(shell,'/'); 109625908Smckusick if (namep == NULL) 109725908Smckusick namep = shell; 109826497Sminshall (void) strcpy(shellnam,"-"); 109926497Sminshall (void) strcat(shellnam, ++namep); 110026049Sminshall if (strcmp(namep, "sh") != 0) 110126049Sminshall shellnam[0] = '+'; 110226049Sminshall if (debug) { 110326049Sminshall printf ("%s\n", shell); 110426497Sminshall (void) fflush (stdout); 110511756Ssam } 110626049Sminshall if (argc > 1) { 110726049Sminshall execl(shell,shellnam,"-c",altarg,(char *)0); 110826049Sminshall } 110926049Sminshall else { 111026049Sminshall execl(shell,shellnam,(char *)0); 111126049Sminshall } 111225908Smckusick perror(shell); 111326049Sminshall code = -1; 111411756Ssam exit(1); 111526049Sminshall } 111611756Ssam if (pid > 0) 111711756Ssam while (wait(&status) != pid) 111811756Ssam ; 111926497Sminshall (void) signal(SIGINT, old1); 112026497Sminshall (void) signal(SIGQUIT, old2); 112126049Sminshall if (pid == -1) { 112211756Ssam perror("Try again later"); 112326049Sminshall code = -1; 112426049Sminshall } 112526049Sminshall else { 112626049Sminshall code = 0; 112726049Sminshall } 112811756Ssam return (0); 112910294Ssam } 113010294Ssam 113110294Ssam /* 113210294Ssam * Send new user information (re-login) 113310294Ssam */ 113410294Ssam user(argc, argv) 113510294Ssam int argc; 113610294Ssam char **argv; 113710294Ssam { 1138*35658Sbostic char acct[80], *getpass(); 113926049Sminshall int n, aflag = 0; 114010294Ssam 114110294Ssam if (argc < 2) { 114226497Sminshall (void) strcat(line, " "); 114310294Ssam printf("(username) "); 114426497Sminshall (void) gets(&line[strlen(line)]); 114510294Ssam makeargv(); 114610294Ssam argc = margc; 114710294Ssam argv = margv; 114810294Ssam } 114910294Ssam if (argc > 4) { 115010294Ssam printf("usage: %s username [password] [account]\n", argv[0]); 115126049Sminshall code = -1; 115211756Ssam return (0); 115310294Ssam } 115410294Ssam n = command("USER %s", argv[1]); 115510294Ssam if (n == CONTINUE) { 115610294Ssam if (argc < 3 ) 1157*35658Sbostic argv[2] = getpass("Password: "), argc++; 115810294Ssam n = command("PASS %s", argv[2]); 115910294Ssam } 116010294Ssam if (n == CONTINUE) { 116110294Ssam if (argc < 4) { 116210294Ssam printf("Account: "); (void) fflush(stdout); 116310294Ssam (void) fgets(acct, sizeof(acct) - 1, stdin); 116410294Ssam acct[strlen(acct) - 1] = '\0'; 116510294Ssam argv[3] = acct; argc++; 116610294Ssam } 116726049Sminshall n = command("ACCT %s", argv[3]); 116826049Sminshall aflag++; 116910294Ssam } 117010294Ssam if (n != COMPLETE) { 117126497Sminshall fprintf(stdout, "Login failed.\n"); 117210294Ssam return (0); 117310294Ssam } 117426049Sminshall if (!aflag && argc == 4) { 117526049Sminshall (void) command("ACCT %s", argv[3]); 117626049Sminshall } 117710294Ssam return (1); 117810294Ssam } 117910294Ssam 118010294Ssam /* 118110294Ssam * Print working directory. 118210294Ssam */ 118310294Ssam /*VARARGS*/ 118410294Ssam pwd() 118510294Ssam { 118611756Ssam 118726049Sminshall (void) command("PWD"); 118810294Ssam } 118910294Ssam 119010294Ssam /* 119110294Ssam * Make a directory. 119210294Ssam */ 119310294Ssam makedir(argc, argv) 119410294Ssam char *argv[]; 119510294Ssam { 119610294Ssam 119710294Ssam if (argc < 2) { 119826497Sminshall (void) strcat(line, " "); 119910294Ssam printf("(directory-name) "); 120026497Sminshall (void) gets(&line[strlen(line)]); 120110294Ssam makeargv(); 120210294Ssam argc = margc; 120310294Ssam argv = margv; 120410294Ssam } 120510294Ssam if (argc < 2) { 120626049Sminshall printf("usage: %s directory-name\n", argv[0]); 120726049Sminshall code = -1; 120810294Ssam return; 120910294Ssam } 121026049Sminshall (void) command("MKD %s", argv[1]); 121110294Ssam } 121210294Ssam 121310294Ssam /* 121410294Ssam * Remove a directory. 121510294Ssam */ 121610294Ssam removedir(argc, argv) 121710294Ssam char *argv[]; 121810294Ssam { 121910294Ssam 122010294Ssam if (argc < 2) { 122126497Sminshall (void) strcat(line, " "); 122210294Ssam printf("(directory-name) "); 122326497Sminshall (void) gets(&line[strlen(line)]); 122410294Ssam makeargv(); 122510294Ssam argc = margc; 122610294Ssam argv = margv; 122710294Ssam } 122810294Ssam if (argc < 2) { 122926049Sminshall printf("usage: %s directory-name\n", argv[0]); 123026049Sminshall code = -1; 123110294Ssam return; 123210294Ssam } 123326049Sminshall (void) command("RMD %s", argv[1]); 123410294Ssam } 123510294Ssam 123610294Ssam /* 123710294Ssam * Send a line, verbatim, to the remote machine. 123810294Ssam */ 123910294Ssam quote(argc, argv) 124010294Ssam char *argv[]; 124110294Ssam { 124210294Ssam int i; 124310294Ssam char buf[BUFSIZ]; 124410294Ssam 124510294Ssam if (argc < 2) { 124626497Sminshall (void) strcat(line, " "); 124710294Ssam printf("(command line to send) "); 124826497Sminshall (void) gets(&line[strlen(line)]); 124910294Ssam makeargv(); 125010294Ssam argc = margc; 125110294Ssam argv = margv; 125210294Ssam } 125310294Ssam if (argc < 2) { 125410294Ssam printf("usage: %s line-to-send\n", argv[0]); 125526049Sminshall code = -1; 125610294Ssam return; 125710294Ssam } 125826497Sminshall (void) strcpy(buf, argv[1]); 125910294Ssam for (i = 2; i < argc; i++) { 126026497Sminshall (void) strcat(buf, " "); 126126497Sminshall (void) strcat(buf, argv[i]); 126210294Ssam } 126326049Sminshall if (command(buf) == PRELIM) { 126426049Sminshall while (getreply(0) == PRELIM); 126526049Sminshall } 126610294Ssam } 126710294Ssam 126810294Ssam /* 126910294Ssam * Ask the other side for help. 127010294Ssam */ 127110294Ssam rmthelp(argc, argv) 127210294Ssam char *argv[]; 127310294Ssam { 127410294Ssam int oldverbose = verbose; 127510294Ssam 127610294Ssam verbose = 1; 127710294Ssam (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]); 127810294Ssam verbose = oldverbose; 127910294Ssam } 128010294Ssam 128110294Ssam /* 128210294Ssam * Terminate session and exit. 128310294Ssam */ 128410294Ssam /*VARARGS*/ 128510294Ssam quit() 128610294Ssam { 128710294Ssam 128818286Sralph if (connected) 128918286Sralph disconnect(); 129026049Sminshall pswitch(1); 129126049Sminshall if (connected) { 129226049Sminshall disconnect(); 129326049Sminshall } 129410294Ssam exit(0); 129510294Ssam } 129610294Ssam 129710294Ssam /* 129810294Ssam * Terminate session, but don't exit. 129910294Ssam */ 130010294Ssam disconnect() 130110294Ssam { 130210294Ssam extern FILE *cout; 130310294Ssam extern int data; 130410294Ssam 130510294Ssam if (!connected) 130610294Ssam return; 130710294Ssam (void) command("QUIT"); 130826049Sminshall if (cout) { 130926049Sminshall (void) fclose(cout); 131026049Sminshall } 131110294Ssam cout = NULL; 131210294Ssam connected = 0; 131310294Ssam data = -1; 131426049Sminshall if (!proxy) { 131526049Sminshall macnum = 0; 131626049Sminshall } 131710294Ssam } 131811353Ssam 131911650Ssam confirm(cmd, file) 132011353Ssam char *cmd, *file; 132111353Ssam { 132211353Ssam char line[BUFSIZ]; 132311353Ssam 132411353Ssam if (!interactive) 132511650Ssam return (1); 132611353Ssam printf("%s %s? ", cmd, file); 132726497Sminshall (void) fflush(stdout); 132826497Sminshall (void) gets(line); 132911650Ssam return (*line != 'n' && *line != 'N'); 133011353Ssam } 133111353Ssam 133211353Ssam fatal(msg) 133311353Ssam char *msg; 133411353Ssam { 133511353Ssam 133626497Sminshall fprintf(stderr, "ftp: %s\n", msg); 133711353Ssam exit(1); 133811353Ssam } 133911353Ssam 134011353Ssam /* 134111353Ssam * Glob a local file name specification with 134211353Ssam * the expectation of a single return value. 134311353Ssam * Can't control multiple values being expanded 134411353Ssam * from the expression, we return only the first. 134511353Ssam */ 134611353Ssam globulize(cpp) 134711353Ssam char **cpp; 134811353Ssam { 134911353Ssam char **globbed; 135011353Ssam 135111353Ssam if (!doglob) 135211353Ssam return (1); 135311353Ssam globbed = glob(*cpp); 135411353Ssam if (globerr != NULL) { 135511353Ssam printf("%s: %s\n", *cpp, globerr); 135611353Ssam if (globbed) 135711353Ssam blkfree(globbed); 135811353Ssam return (0); 135911353Ssam } 136011353Ssam if (globbed) { 136111353Ssam *cpp = *globbed++; 136211353Ssam /* don't waste too much memory */ 136311353Ssam if (*globbed) 136411353Ssam blkfree(globbed); 136511353Ssam } 136611353Ssam return (1); 136711353Ssam } 136826049Sminshall 136926049Sminshall account(argc,argv) 137026049Sminshall 137126049Sminshall int argc; 137226049Sminshall char **argv; 137326049Sminshall { 1374*35658Sbostic char acct[50], *getpass(), *ap; 137526049Sminshall 137626049Sminshall if (argc > 1) { 137726049Sminshall ++argv; 137826049Sminshall --argc; 137926049Sminshall (void) strncpy(acct,*argv,49); 138026049Sminshall acct[50] = '\0'; 138126049Sminshall while (argc > 1) { 138226049Sminshall --argc; 138326049Sminshall ++argv; 138426049Sminshall (void) strncat(acct,*argv, 49-strlen(acct)); 138526049Sminshall } 138626049Sminshall ap = acct; 138726049Sminshall } 138826049Sminshall else { 1389*35658Sbostic ap = getpass("Account:"); 139026049Sminshall } 139126049Sminshall (void) command("ACCT %s", ap); 139226049Sminshall } 139326049Sminshall 139426049Sminshall jmp_buf abortprox; 139526049Sminshall 139626049Sminshall proxabort() 139726049Sminshall { 139826049Sminshall extern int proxy; 139926049Sminshall 140026049Sminshall if (!proxy) { 140126049Sminshall pswitch(1); 140226049Sminshall } 140326049Sminshall if (connected) { 140426049Sminshall proxflag = 1; 140526049Sminshall } 140626049Sminshall else { 140726049Sminshall proxflag = 0; 140826049Sminshall } 140926049Sminshall pswitch(0); 141026049Sminshall longjmp(abortprox,1); 141126049Sminshall } 141226049Sminshall 141326049Sminshall doproxy(argc,argv) 141426049Sminshall int argc; 141526049Sminshall char *argv[]; 141626049Sminshall { 141726049Sminshall int (*oldintr)(), proxabort(); 141826049Sminshall register struct cmd *c; 141926049Sminshall struct cmd *getcmd(); 142026049Sminshall extern struct cmd cmdtab[]; 142126049Sminshall extern jmp_buf abortprox; 142226049Sminshall 142326049Sminshall if (argc < 2) { 142426497Sminshall (void) strcat(line, " "); 142526049Sminshall printf("(command) "); 142626497Sminshall (void) gets(&line[strlen(line)]); 142726049Sminshall makeargv(); 142826049Sminshall argc = margc; 142926049Sminshall argv = margv; 143026049Sminshall } 143126049Sminshall if (argc < 2) { 143226049Sminshall printf("usage:%s command\n", argv[0]); 143326049Sminshall code = -1; 143426049Sminshall return; 143526049Sminshall } 143626049Sminshall c = getcmd(argv[1]); 143726049Sminshall if (c == (struct cmd *) -1) { 143826049Sminshall printf("?Ambiguous command\n"); 143926497Sminshall (void) fflush(stdout); 144026049Sminshall code = -1; 144126049Sminshall return; 144226049Sminshall } 144326049Sminshall if (c == 0) { 144426049Sminshall printf("?Invalid command\n"); 144526497Sminshall (void) fflush(stdout); 144626049Sminshall code = -1; 144726049Sminshall return; 144826049Sminshall } 144926049Sminshall if (!c->c_proxy) { 145026049Sminshall printf("?Invalid proxy command\n"); 145126497Sminshall (void) fflush(stdout); 145226049Sminshall code = -1; 145326049Sminshall return; 145426049Sminshall } 145526049Sminshall if (setjmp(abortprox)) { 145626049Sminshall code = -1; 145726049Sminshall return; 145826049Sminshall } 145926049Sminshall oldintr = signal(SIGINT, proxabort); 146026049Sminshall pswitch(1); 146126049Sminshall if (c->c_conn && !connected) { 146226049Sminshall printf("Not connected\n"); 146326497Sminshall (void) fflush(stdout); 146426049Sminshall pswitch(0); 146526049Sminshall (void) signal(SIGINT, oldintr); 146626049Sminshall code = -1; 146726049Sminshall return; 146826049Sminshall } 146926049Sminshall (*c->c_handler)(argc-1, argv+1); 147026049Sminshall if (connected) { 147126049Sminshall proxflag = 1; 147226049Sminshall } 147326049Sminshall else { 147426049Sminshall proxflag = 0; 147526049Sminshall } 147626049Sminshall pswitch(0); 147726049Sminshall (void) signal(SIGINT, oldintr); 147826049Sminshall } 147926049Sminshall 148026049Sminshall setcase() 148126049Sminshall { 148226049Sminshall mcase = !mcase; 148326049Sminshall printf("Case mapping %s.\n", onoff(mcase)); 148426049Sminshall code = mcase; 148526049Sminshall } 148626049Sminshall 148726049Sminshall setcr() 148826049Sminshall { 148926049Sminshall crflag = !crflag; 149026049Sminshall printf("Carriage Return stripping %s.\n", onoff(crflag)); 149126049Sminshall code = crflag; 149226049Sminshall } 149326049Sminshall 149426049Sminshall setntrans(argc,argv) 149526049Sminshall int argc; 149626049Sminshall char *argv[]; 149726049Sminshall { 149826049Sminshall if (argc == 1) { 149926049Sminshall ntflag = 0; 150026049Sminshall printf("Ntrans off.\n"); 150126049Sminshall code = ntflag; 150226049Sminshall return; 150326049Sminshall } 150426049Sminshall ntflag++; 150526049Sminshall code = ntflag; 150626049Sminshall (void) strncpy(ntin, argv[1], 16); 150726049Sminshall ntin[16] = '\0'; 150826049Sminshall if (argc == 2) { 150926049Sminshall ntout[0] = '\0'; 151026049Sminshall return; 151126049Sminshall } 151226049Sminshall (void) strncpy(ntout, argv[2], 16); 151326049Sminshall ntout[16] = '\0'; 151426049Sminshall } 151526049Sminshall 151626049Sminshall char * 151726049Sminshall dotrans(name) 151826049Sminshall char *name; 151926049Sminshall { 152026049Sminshall static char new[MAXPATHLEN]; 152126049Sminshall char *cp1, *cp2 = new; 152226049Sminshall register int i, ostop, found; 152326049Sminshall 152426049Sminshall for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++); 152526049Sminshall for (cp1 = name; *cp1; cp1++) { 152626049Sminshall found = 0; 152726049Sminshall for (i = 0; *(ntin + i) && i < 16; i++) { 152826049Sminshall if (*cp1 == *(ntin + i)) { 152926049Sminshall found++; 153026049Sminshall if (i < ostop) { 153126049Sminshall *cp2++ = *(ntout + i); 153226049Sminshall } 153326049Sminshall break; 153426049Sminshall } 153526049Sminshall } 153626049Sminshall if (!found) { 153726049Sminshall *cp2++ = *cp1; 153826049Sminshall } 153926049Sminshall } 154026049Sminshall *cp2 = '\0'; 154126049Sminshall return(new); 154226049Sminshall } 154326049Sminshall 154426049Sminshall setnmap(argc, argv) 154526049Sminshall int argc; 154626049Sminshall char *argv[]; 154726049Sminshall { 154826049Sminshall char *cp; 154926049Sminshall 155026049Sminshall if (argc == 1) { 155126049Sminshall mapflag = 0; 155226049Sminshall printf("Nmap off.\n"); 155326049Sminshall code = mapflag; 155426049Sminshall return; 155526049Sminshall } 155626049Sminshall if (argc < 3) { 155726497Sminshall (void) strcat(line, " "); 155826049Sminshall printf("(mapout) "); 155926497Sminshall (void) gets(&line[strlen(line)]); 156026049Sminshall makeargv(); 156126049Sminshall argc = margc; 156226049Sminshall argv = margv; 156326049Sminshall } 156426049Sminshall if (argc < 3) { 156526049Sminshall printf("Usage: %s [mapin mapout]\n",argv[0]); 156626049Sminshall code = -1; 156726049Sminshall return; 156826049Sminshall } 156926049Sminshall mapflag = 1; 157026049Sminshall code = 1; 157126049Sminshall cp = index(altarg, ' '); 157226049Sminshall if (proxy) { 157326049Sminshall while(*++cp == ' '); 157426049Sminshall altarg = cp; 157526049Sminshall cp = index(altarg, ' '); 157626049Sminshall } 157726049Sminshall *cp = '\0'; 157826049Sminshall (void) strncpy(mapin, altarg, MAXPATHLEN - 1); 157926049Sminshall while (*++cp == ' '); 158026049Sminshall (void) strncpy(mapout, cp, MAXPATHLEN - 1); 158126049Sminshall } 158226049Sminshall 158326049Sminshall char * 158426049Sminshall domap(name) 158526049Sminshall char *name; 158626049Sminshall { 158726049Sminshall static char new[MAXPATHLEN]; 158826049Sminshall register char *cp1 = name, *cp2 = mapin; 158926049Sminshall char *tp[9], *te[9]; 159026049Sminshall int i, toks[9], toknum, match = 1; 159126049Sminshall 159226049Sminshall for (i=0; i < 9; ++i) { 159326049Sminshall toks[i] = 0; 159426049Sminshall } 159526049Sminshall while (match && *cp1 && *cp2) { 159626049Sminshall switch (*cp2) { 159726049Sminshall case '\\': 159826049Sminshall if (*++cp2 != *cp1) { 159926049Sminshall match = 0; 160026049Sminshall } 160126049Sminshall break; 160226049Sminshall case '$': 160326049Sminshall if (*(cp2+1) >= '1' && (*cp2+1) <= '9') { 160426049Sminshall if (*cp1 != *(++cp2+1)) { 160526049Sminshall toks[toknum = *cp2 - '1']++; 160626049Sminshall tp[toknum] = cp1; 160726049Sminshall while (*++cp1 && *(cp2+1) 160826049Sminshall != *cp1); 160926049Sminshall te[toknum] = cp1; 161026049Sminshall } 161126049Sminshall cp2++; 161226049Sminshall break; 161326049Sminshall } 161426049Sminshall /* intentional drop through */ 161526049Sminshall default: 161626049Sminshall if (*cp2 != *cp1) { 161726049Sminshall match = 0; 161826049Sminshall } 161926049Sminshall break; 162026049Sminshall } 162126049Sminshall if (*cp1) { 162226049Sminshall cp1++; 162326049Sminshall } 162426049Sminshall if (*cp2) { 162526049Sminshall cp2++; 162626049Sminshall } 162726049Sminshall } 162826049Sminshall cp1 = new; 162926049Sminshall *cp1 = '\0'; 163026049Sminshall cp2 = mapout; 163126049Sminshall while (*cp2) { 163226049Sminshall match = 0; 163326049Sminshall switch (*cp2) { 163426049Sminshall case '\\': 163526049Sminshall if (*(cp2 + 1)) { 163626049Sminshall *cp1++ = *++cp2; 163726049Sminshall } 163826049Sminshall break; 163926049Sminshall case '[': 164026049Sminshall LOOP: 164126049Sminshall if (*++cp2 == '$' && isdigit(*(cp2+1))) { 164226049Sminshall if (*++cp2 == '0') { 164326049Sminshall char *cp3 = name; 164426049Sminshall 164526049Sminshall while (*cp3) { 164626049Sminshall *cp1++ = *cp3++; 164726049Sminshall } 164826049Sminshall match = 1; 164926049Sminshall } 165026049Sminshall else if (toks[toknum = *cp2 - '1']) { 165126049Sminshall char *cp3 = tp[toknum]; 165226049Sminshall 165326049Sminshall while (cp3 != te[toknum]) { 165426049Sminshall *cp1++ = *cp3++; 165526049Sminshall } 165626049Sminshall match = 1; 165726049Sminshall } 165826049Sminshall } 165926049Sminshall else { 166026049Sminshall while (*cp2 && *cp2 != ',' && 166126049Sminshall *cp2 != ']') { 166226049Sminshall if (*cp2 == '\\') { 166326049Sminshall cp2++; 166426049Sminshall } 166526049Sminshall else if (*cp2 == '$' && 166626049Sminshall isdigit(*(cp2+1))) { 166726049Sminshall if (*++cp2 == '0') { 166826049Sminshall char *cp3 = name; 166926049Sminshall 167026049Sminshall while (*cp3) { 167126049Sminshall *cp1++ = *cp3++; 167226049Sminshall } 167326049Sminshall } 167426049Sminshall else if (toks[toknum = 167526049Sminshall *cp2 - '1']) { 167626049Sminshall char *cp3=tp[toknum]; 167726049Sminshall 167826049Sminshall while (cp3 != 167926049Sminshall te[toknum]) { 168026049Sminshall *cp1++ = *cp3++; 168126049Sminshall } 168226049Sminshall } 168326049Sminshall } 168426049Sminshall else if (*cp2) { 168526049Sminshall *cp1++ = *cp2++; 168626049Sminshall } 168726049Sminshall } 168826049Sminshall if (!*cp2) { 168926049Sminshall printf("nmap: unbalanced brackets\n"); 169026049Sminshall return(name); 169126049Sminshall } 169226049Sminshall match = 1; 169326049Sminshall cp2--; 169426049Sminshall } 169526049Sminshall if (match) { 169626049Sminshall while (*++cp2 && *cp2 != ']') { 169726049Sminshall if (*cp2 == '\\' && *(cp2 + 1)) { 169826049Sminshall cp2++; 169926049Sminshall } 170026049Sminshall } 170126049Sminshall if (!*cp2) { 170226049Sminshall printf("nmap: unbalanced brackets\n"); 170326049Sminshall return(name); 170426049Sminshall } 170526049Sminshall break; 170626049Sminshall } 170726049Sminshall switch (*++cp2) { 170826049Sminshall case ',': 170926049Sminshall goto LOOP; 171026049Sminshall case ']': 171126049Sminshall break; 171226049Sminshall default: 171326049Sminshall cp2--; 171426049Sminshall goto LOOP; 171526049Sminshall } 171626049Sminshall break; 171726049Sminshall case '$': 171826049Sminshall if (isdigit(*(cp2 + 1))) { 171926049Sminshall if (*++cp2 == '0') { 172026049Sminshall char *cp3 = name; 172126049Sminshall 172226049Sminshall while (*cp3) { 172326049Sminshall *cp1++ = *cp3++; 172426049Sminshall } 172526049Sminshall } 172626049Sminshall else if (toks[toknum = *cp2 - '1']) { 172726049Sminshall char *cp3 = tp[toknum]; 172826049Sminshall 172926049Sminshall while (cp3 != te[toknum]) { 173026049Sminshall *cp1++ = *cp3++; 173126049Sminshall } 173226049Sminshall } 173326049Sminshall break; 173426049Sminshall } 173526049Sminshall /* intentional drop through */ 173626049Sminshall default: 173726049Sminshall *cp1++ = *cp2; 173826049Sminshall break; 173926049Sminshall } 174026049Sminshall cp2++; 174126049Sminshall } 174226049Sminshall *cp1 = '\0'; 174326049Sminshall if (!*new) { 174426049Sminshall return(name); 174526049Sminshall } 174626049Sminshall return(new); 174726049Sminshall } 174826049Sminshall 174926049Sminshall setsunique() 175026049Sminshall { 175126049Sminshall sunique = !sunique; 175226049Sminshall printf("Store unique %s.\n", onoff(sunique)); 175326049Sminshall code = sunique; 175426049Sminshall } 175526049Sminshall 175626049Sminshall setrunique() 175726049Sminshall { 175826049Sminshall runique = !runique; 175926049Sminshall printf("Receive unique %s.\n", onoff(runique)); 176026049Sminshall code = runique; 176126049Sminshall } 176226049Sminshall 176326049Sminshall /* change directory to perent directory */ 176426049Sminshall cdup() 176526049Sminshall { 176626049Sminshall (void) command("CDUP"); 176726049Sminshall } 176826049Sminshall 176926049Sminshall macdef(argc, argv) 177026049Sminshall int argc; 177126049Sminshall char *argv[]; 177226049Sminshall { 177326049Sminshall char *tmp; 177426049Sminshall int c; 177526049Sminshall 177626049Sminshall if (macnum == 16) { 177726049Sminshall printf("Limit of 16 macros have already been defined\n"); 177826049Sminshall code = -1; 177926049Sminshall return; 178026049Sminshall } 178126049Sminshall if (argc < 2) { 178226497Sminshall (void) strcat(line, " "); 178326049Sminshall printf("(macro name) "); 178426497Sminshall (void) gets(&line[strlen(line)]); 178526049Sminshall makeargv(); 178626049Sminshall argc = margc; 178726049Sminshall argv = margv; 178826049Sminshall } 178926049Sminshall if (argc != 2) { 179026049Sminshall printf("Usage: %s macro_name\n",argv[0]); 179126049Sminshall code = -1; 179226049Sminshall return; 179326049Sminshall } 179426049Sminshall if (interactive) { 179526049Sminshall printf("Enter macro line by line, terminating it with a null line\n"); 179626049Sminshall } 179726497Sminshall (void) strncpy(macros[macnum].mac_name, argv[1], 8); 179826049Sminshall if (macnum == 0) { 179926049Sminshall macros[macnum].mac_start = macbuf; 180026049Sminshall } 180126049Sminshall else { 180226049Sminshall macros[macnum].mac_start = macros[macnum - 1].mac_end + 1; 180326049Sminshall } 180426049Sminshall tmp = macros[macnum].mac_start; 180526049Sminshall while (tmp != macbuf+4096) { 180626049Sminshall if ((c = getchar()) == EOF) { 180726049Sminshall printf("macdef:end of file encountered\n"); 180826049Sminshall code = -1; 180926049Sminshall return; 181026049Sminshall } 181126049Sminshall if ((*tmp = c) == '\n') { 181226049Sminshall if (tmp == macros[macnum].mac_start) { 181326049Sminshall macros[macnum++].mac_end = tmp; 181426049Sminshall code = 0; 181526049Sminshall return; 181626049Sminshall } 181726049Sminshall if (*(tmp-1) == '\0') { 181826049Sminshall macros[macnum++].mac_end = tmp - 1; 181926049Sminshall code = 0; 182026049Sminshall return; 182126049Sminshall } 182226049Sminshall *tmp = '\0'; 182326049Sminshall } 182426049Sminshall tmp++; 182526049Sminshall } 182626049Sminshall while (1) { 182726049Sminshall while ((c = getchar()) != '\n' && c != EOF); 182826049Sminshall if (c == EOF || getchar() == '\n') { 182926049Sminshall printf("Macro not defined - 4k buffer exceeded\n"); 183026049Sminshall code = -1; 183126049Sminshall return; 183226049Sminshall } 183326049Sminshall } 183426049Sminshall } 1835