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*36421Sbostic static char sccsid[] = "@(#)cmds.c 5.11 (Berkeley) 12/14/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); 396*36421Sbostic if (gargs) { 39711650Ssam blkfree(gargs); 398*36421Sbostic free(gargs); 399*36421Sbostic } 40013212Ssam continue; 40111353Ssam } 40226049Sminshall for (cpp = gargs; cpp && *cpp != NULL; cpp++) { 40326049Sminshall if (mflag && confirm(argv[0], *cpp)) { 40426049Sminshall tp = (ntflag) ? dotrans(*cpp) : *cpp; 40526049Sminshall tp = (mapflag) ? domap(tp) : tp; 40626049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 40726049Sminshall *cpp, tp); 40826049Sminshall if (!mflag && fromatty) { 40926049Sminshall ointer = interactive; 41026049Sminshall interactive = 1; 41126049Sminshall if (confirm("Continue with","mput")) { 41226049Sminshall mflag++; 41326049Sminshall } 41426049Sminshall interactive = ointer; 41526049Sminshall } 41626049Sminshall } 41726049Sminshall } 418*36421Sbostic if (gargs != NULL) { 41913212Ssam blkfree(gargs); 420*36421Sbostic free(gargs); 421*36421Sbostic } 42211353Ssam } 42326049Sminshall (void) signal(SIGINT, oldintr); 42426049Sminshall mflag = 0; 42511353Ssam } 42611353Ssam 42711353Ssam /* 42811353Ssam * Receive one file. 42911353Ssam */ 43010294Ssam get(argc, argv) 43110294Ssam char *argv[]; 43210294Ssam { 43326049Sminshall int loc = 0; 43410294Ssam 43526049Sminshall if (argc == 2) { 43626049Sminshall argc++; 43726049Sminshall argv[2] = argv[1]; 43826049Sminshall loc++; 43926049Sminshall } 44010294Ssam if (argc < 2) { 44126497Sminshall (void) strcat(line, " "); 44210294Ssam printf("(remote-file) "); 44326497Sminshall (void) gets(&line[strlen(line)]); 44410294Ssam makeargv(); 44510294Ssam argc = margc; 44610294Ssam argv = margv; 44710294Ssam } 44810294Ssam if (argc < 2) { 44910294Ssam usage: 45026049Sminshall printf("usage: %s remote-file [ local-file ]\n", argv[0]); 45126049Sminshall code = -1; 45210294Ssam return; 45310294Ssam } 45410294Ssam if (argc < 3) { 45526497Sminshall (void) strcat(line, " "); 45610294Ssam printf("(local-file) "); 45726497Sminshall (void) gets(&line[strlen(line)]); 45810294Ssam makeargv(); 45910294Ssam argc = margc; 46010294Ssam argv = margv; 46110294Ssam } 46210294Ssam if (argc < 3) 46310294Ssam goto usage; 46426049Sminshall if (!globulize(&argv[2])) { 46526049Sminshall code = -1; 46611353Ssam return; 46726049Sminshall } 46826049Sminshall if (loc && mcase) { 46926049Sminshall char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN]; 47026049Sminshall 47126049Sminshall while (*tp && !islower(*tp)) { 47226049Sminshall tp++; 47326049Sminshall } 47426049Sminshall if (!*tp) { 47526049Sminshall tp = argv[2]; 47626049Sminshall tp2 = tmpbuf; 47726049Sminshall while ((*tp2 = *tp) != NULL) { 47826049Sminshall if (isupper(*tp2)) { 47926049Sminshall *tp2 = 'a' + *tp2 - 'A'; 48026049Sminshall } 48126049Sminshall tp++; 48226049Sminshall tp2++; 48326049Sminshall } 48426049Sminshall argv[2] = tmpbuf; 48526049Sminshall } 48626049Sminshall } 48726049Sminshall if (loc && ntflag) { 48826049Sminshall argv[2] = dotrans(argv[2]); 48926049Sminshall } 49026049Sminshall if (loc && mapflag) { 49126049Sminshall argv[2] = domap(argv[2]); 49226049Sminshall } 49311650Ssam recvrequest("RETR", argv[2], argv[1], "w"); 49410294Ssam } 49510294Ssam 49626049Sminshall mabort() 49726049Sminshall { 49826049Sminshall int ointer; 49926049Sminshall extern jmp_buf jabort; 50026049Sminshall 50126049Sminshall printf("\n"); 50226049Sminshall (void) fflush(stdout); 50326049Sminshall if (mflag && fromatty) { 50426049Sminshall ointer = interactive; 50526049Sminshall interactive = 1; 50626049Sminshall if (confirm("Continue with", mname)) { 50726049Sminshall interactive = ointer; 50826049Sminshall longjmp(jabort,0); 50926049Sminshall } 51026049Sminshall interactive = ointer; 51126049Sminshall } 51226049Sminshall mflag = 0; 51326049Sminshall longjmp(jabort,0); 51426049Sminshall } 51526049Sminshall 51611353Ssam /* 51711353Ssam * Get multiple files. 51811353Ssam */ 51911353Ssam mget(argc, argv) 52011353Ssam char *argv[]; 52111353Ssam { 52226049Sminshall char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN]; 52326049Sminshall int ointer, (*oldintr)(), mabort(); 52426049Sminshall extern jmp_buf jabort; 52511353Ssam 52611353Ssam if (argc < 2) { 52726497Sminshall (void) strcat(line, " "); 52811756Ssam printf("(remote-files) "); 52926497Sminshall (void) gets(&line[strlen(line)]); 53011353Ssam makeargv(); 53111353Ssam argc = margc; 53211353Ssam argv = margv; 53311353Ssam } 53411353Ssam if (argc < 2) { 53526049Sminshall printf("usage:%s remote-files\n", argv[0]); 53626049Sminshall code = -1; 53711353Ssam return; 53811353Ssam } 53926049Sminshall mname = argv[0]; 54026049Sminshall mflag = 1; 54126049Sminshall oldintr = signal(SIGINT,mabort); 54226049Sminshall (void) setjmp(jabort); 54326497Sminshall while ((cp = remglob(argv,proxy)) != NULL) { 54426049Sminshall if (*cp == '\0') { 54526049Sminshall mflag = 0; 54626049Sminshall continue; 54726049Sminshall } 54826049Sminshall if (mflag && confirm(argv[0], cp)) { 54926049Sminshall tp = cp; 55026049Sminshall if (mcase) { 55126049Sminshall while (*tp && !islower(*tp)) { 55226049Sminshall tp++; 55326049Sminshall } 55426049Sminshall if (!*tp) { 55526049Sminshall tp = cp; 55626049Sminshall tp2 = tmpbuf; 55726049Sminshall while ((*tp2 = *tp) != NULL) { 55826049Sminshall if (isupper(*tp2)) { 55926049Sminshall *tp2 = 'a' + *tp2 - 'A'; 56026049Sminshall } 56126049Sminshall tp++; 56226049Sminshall tp2++; 56326049Sminshall } 56426049Sminshall } 56526049Sminshall tp = tmpbuf; 56626049Sminshall } 56726049Sminshall if (ntflag) { 56826049Sminshall tp = dotrans(tp); 56926049Sminshall } 57026049Sminshall if (mapflag) { 57126049Sminshall tp = domap(tp); 57226049Sminshall } 57326049Sminshall recvrequest("RETR", tp, cp, "w"); 57426049Sminshall if (!mflag && fromatty) { 57526049Sminshall ointer = interactive; 57626049Sminshall interactive = 1; 57726049Sminshall if (confirm("Continue with","mget")) { 57826049Sminshall mflag++; 57926049Sminshall } 58026049Sminshall interactive = ointer; 58126049Sminshall } 58226049Sminshall } 58326049Sminshall } 58426049Sminshall (void) signal(SIGINT,oldintr); 58526049Sminshall mflag = 0; 58611650Ssam } 58711650Ssam 58811650Ssam char * 58926497Sminshall remglob(argv,doswitch) 59011650Ssam char *argv[]; 59126497Sminshall int doswitch; 59211650Ssam { 59311756Ssam char temp[16]; 59411650Ssam static char buf[MAXPATHLEN]; 59511650Ssam static FILE *ftemp = NULL; 59611650Ssam static char **args; 59713212Ssam int oldverbose, oldhash; 59811756Ssam char *cp, *mode; 59911650Ssam 60026049Sminshall if (!mflag) { 60126049Sminshall if (!doglob) { 60226049Sminshall args = NULL; 60326049Sminshall } 60426049Sminshall else { 60526049Sminshall if (ftemp) { 60626497Sminshall (void) fclose(ftemp); 60726049Sminshall ftemp = NULL; 60826049Sminshall } 60926049Sminshall } 61026049Sminshall return(NULL); 61126049Sminshall } 61211650Ssam if (!doglob) { 61311756Ssam if (args == NULL) 61411650Ssam args = argv; 61511650Ssam if ((cp = *++args) == NULL) 61611650Ssam args = NULL; 61711650Ssam return (cp); 61811353Ssam } 61911650Ssam if (ftemp == NULL) { 62026497Sminshall (void) strcpy(temp, "/tmp/ftpXXXXXX"); 62126497Sminshall (void) mktemp(temp); 62211650Ssam oldverbose = verbose, verbose = 0; 62313212Ssam oldhash = hash, hash = 0; 62426049Sminshall if (doswitch) { 62526049Sminshall pswitch(!proxy); 62626049Sminshall } 62711756Ssam for (mode = "w"; *++argv != NULL; mode = "a") 62811756Ssam recvrequest ("NLST", temp, *argv, mode); 62926049Sminshall if (doswitch) { 63026049Sminshall pswitch(!proxy); 63126049Sminshall } 63213212Ssam verbose = oldverbose; hash = oldhash; 63311650Ssam ftemp = fopen(temp, "r"); 63426497Sminshall (void) unlink(temp); 63511650Ssam if (ftemp == NULL) { 63611650Ssam printf("can't find list of remote files, oops\n"); 63711756Ssam return (NULL); 63811353Ssam } 63911353Ssam } 64011650Ssam if (fgets(buf, sizeof (buf), ftemp) == NULL) { 64126497Sminshall (void) fclose(ftemp), ftemp = NULL; 64211650Ssam return (NULL); 64311353Ssam } 64411650Ssam if ((cp = index(buf, '\n')) != NULL) 64511650Ssam *cp = '\0'; 64611650Ssam return (buf); 64711353Ssam } 64811353Ssam 64910294Ssam char * 65010294Ssam onoff(bool) 65110294Ssam int bool; 65210294Ssam { 65310294Ssam 65410294Ssam return (bool ? "on" : "off"); 65510294Ssam } 65610294Ssam 65710294Ssam /* 65810294Ssam * Show status. 65910294Ssam */ 66026497Sminshall /*ARGSUSED*/ 66110294Ssam status(argc, argv) 66210294Ssam char *argv[]; 66310294Ssam { 66426049Sminshall int i; 66510294Ssam 66610294Ssam if (connected) 66710294Ssam printf("Connected to %s.\n", hostname); 66810294Ssam else 66910294Ssam printf("Not connected.\n"); 67026049Sminshall if (!proxy) { 67126049Sminshall pswitch(1); 67226049Sminshall if (connected) { 67326049Sminshall printf("Connected for proxy commands to %s.\n", hostname); 67426049Sminshall } 67526049Sminshall else { 67626049Sminshall printf("No proxy connection.\n"); 67726049Sminshall } 67826049Sminshall pswitch(0); 67926049Sminshall } 68010294Ssam printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n", 68110294Ssam modename, typename, formname, structname); 68211353Ssam printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 68311353Ssam onoff(verbose), onoff(bell), onoff(interactive), 68411353Ssam onoff(doglob)); 68526049Sminshall printf("Store unique: %s; Receive unique: %s\n", onoff(sunique), 68626049Sminshall onoff(runique)); 68726049Sminshall printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag)); 68826049Sminshall if (ntflag) { 68926049Sminshall printf("Ntrans: (in) %s (out) %s\n", ntin,ntout); 69026049Sminshall } 69126049Sminshall else { 69226049Sminshall printf("Ntrans: off\n"); 69326049Sminshall } 69426049Sminshall if (mapflag) { 69526049Sminshall printf("Nmap: (in) %s (out) %s\n", mapin, mapout); 69626049Sminshall } 69726049Sminshall else { 69826049Sminshall printf("Nmap: off\n"); 69926049Sminshall } 70014143Ssam printf("Hash mark printing: %s; Use of PORT cmds: %s\n", 70114143Ssam onoff(hash), onoff(sendport)); 70226049Sminshall if (macnum > 0) { 70326049Sminshall printf("Macros:\n"); 70426049Sminshall for (i=0; i<macnum; i++) { 70526049Sminshall printf("\t%s\n",macros[i].mac_name); 70626049Sminshall } 70726049Sminshall } 70826049Sminshall code = 0; 70910294Ssam } 71010294Ssam 71110294Ssam /* 71210294Ssam * Set beep on cmd completed mode. 71310294Ssam */ 71410294Ssam /*VARARGS*/ 71510294Ssam setbell() 71610294Ssam { 71710294Ssam 71810294Ssam bell = !bell; 71910294Ssam printf("Bell mode %s.\n", onoff(bell)); 72026049Sminshall code = bell; 72110294Ssam } 72210294Ssam 72310294Ssam /* 72410294Ssam * Turn on packet tracing. 72510294Ssam */ 72610294Ssam /*VARARGS*/ 72710294Ssam settrace() 72810294Ssam { 72910294Ssam 73010294Ssam trace = !trace; 73110294Ssam printf("Packet tracing %s.\n", onoff(trace)); 73226049Sminshall code = trace; 73310294Ssam } 73410294Ssam 73510294Ssam /* 73611650Ssam * Toggle hash mark printing during transfers. 73711650Ssam */ 73811650Ssam /*VARARGS*/ 73911650Ssam sethash() 74011650Ssam { 74111650Ssam 74211650Ssam hash = !hash; 74311650Ssam printf("Hash mark printing %s", onoff(hash)); 74426049Sminshall code = hash; 74511650Ssam if (hash) 74611650Ssam printf(" (%d bytes/hash mark)", BUFSIZ); 74711650Ssam printf(".\n"); 74811650Ssam } 74911650Ssam 75011650Ssam /* 75110294Ssam * Turn on printing of server echo's. 75210294Ssam */ 75310294Ssam /*VARARGS*/ 75410294Ssam setverbose() 75510294Ssam { 75610294Ssam 75710294Ssam verbose = !verbose; 75810294Ssam printf("Verbose mode %s.\n", onoff(verbose)); 75926049Sminshall code = verbose; 76010294Ssam } 76110294Ssam 76210294Ssam /* 76311650Ssam * Toggle PORT cmd use before each data connection. 76411650Ssam */ 76511650Ssam /*VARARGS*/ 76611650Ssam setport() 76711650Ssam { 76811650Ssam 76911650Ssam sendport = !sendport; 77011650Ssam printf("Use of PORT cmds %s.\n", onoff(sendport)); 77126049Sminshall code = sendport; 77211650Ssam } 77311650Ssam 77411650Ssam /* 77510294Ssam * Turn on interactive prompting 77610294Ssam * during mget, mput, and mdelete. 77710294Ssam */ 77810294Ssam /*VARARGS*/ 77910294Ssam setprompt() 78010294Ssam { 78110294Ssam 78210294Ssam interactive = !interactive; 78310294Ssam printf("Interactive mode %s.\n", onoff(interactive)); 78426049Sminshall code = interactive; 78510294Ssam } 78610294Ssam 78710294Ssam /* 78811353Ssam * Toggle metacharacter interpretation 78911353Ssam * on local file names. 79011353Ssam */ 79111353Ssam /*VARARGS*/ 79211353Ssam setglob() 79311353Ssam { 79411353Ssam 79511353Ssam doglob = !doglob; 79611353Ssam printf("Globbing %s.\n", onoff(doglob)); 79726049Sminshall code = doglob; 79811353Ssam } 79911353Ssam 80011353Ssam /* 80110294Ssam * Set debugging mode on/off and/or 80210294Ssam * set level of debugging. 80310294Ssam */ 80411756Ssam /*VARARGS*/ 80510294Ssam setdebug(argc, argv) 80610294Ssam char *argv[]; 80710294Ssam { 80810294Ssam int val; 80910294Ssam 81010294Ssam if (argc > 1) { 81110294Ssam val = atoi(argv[1]); 81210294Ssam if (val < 0) { 81310294Ssam printf("%s: bad debugging value.\n", argv[1]); 81426049Sminshall code = -1; 81510294Ssam return; 81610294Ssam } 81710294Ssam } else 81810294Ssam val = !debug; 81910294Ssam debug = val; 82010294Ssam if (debug) 82110294Ssam options |= SO_DEBUG; 82210294Ssam else 82310294Ssam options &= ~SO_DEBUG; 82410294Ssam printf("Debugging %s (debug=%d).\n", onoff(debug), debug); 82526049Sminshall code = debug > 0; 82610294Ssam } 82710294Ssam 82810294Ssam /* 82910294Ssam * Set current working directory 83010294Ssam * on remote machine. 83110294Ssam */ 83210294Ssam cd(argc, argv) 83310294Ssam char *argv[]; 83410294Ssam { 83510294Ssam 83610294Ssam if (argc < 2) { 83726497Sminshall (void) strcat(line, " "); 83810294Ssam printf("(remote-directory) "); 83926497Sminshall (void) gets(&line[strlen(line)]); 84010294Ssam makeargv(); 84110294Ssam argc = margc; 84210294Ssam argv = margv; 84310294Ssam } 84410294Ssam if (argc < 2) { 84526049Sminshall printf("usage:%s remote-directory\n", argv[0]); 84626049Sminshall code = -1; 84710294Ssam return; 84810294Ssam } 84910294Ssam (void) command("CWD %s", argv[1]); 85010294Ssam } 85110294Ssam 85210294Ssam /* 85310294Ssam * Set current working directory 85410294Ssam * on local machine. 85510294Ssam */ 85610294Ssam lcd(argc, argv) 85710294Ssam char *argv[]; 85810294Ssam { 85911353Ssam char buf[MAXPATHLEN]; 86010294Ssam 86111353Ssam if (argc < 2) 86211353Ssam argc++, argv[1] = home; 86310294Ssam if (argc != 2) { 86426049Sminshall printf("usage:%s local-directory\n", argv[0]); 86526049Sminshall code = -1; 86610294Ssam return; 86710294Ssam } 86826049Sminshall if (!globulize(&argv[1])) { 86926049Sminshall code = -1; 87011353Ssam return; 87126049Sminshall } 87211353Ssam if (chdir(argv[1]) < 0) { 87310294Ssam perror(argv[1]); 87426049Sminshall code = -1; 87511353Ssam return; 87611353Ssam } 87711353Ssam printf("Local directory now %s\n", getwd(buf)); 87826049Sminshall code = 0; 87910294Ssam } 88010294Ssam 88110294Ssam /* 88210294Ssam * Delete a single file. 88310294Ssam */ 88410294Ssam delete(argc, argv) 88510294Ssam char *argv[]; 88610294Ssam { 88710294Ssam 88810294Ssam if (argc < 2) { 88926497Sminshall (void) strcat(line, " "); 89010294Ssam printf("(remote-file) "); 89126497Sminshall (void) gets(&line[strlen(line)]); 89210294Ssam makeargv(); 89310294Ssam argc = margc; 89410294Ssam argv = margv; 89510294Ssam } 89610294Ssam if (argc < 2) { 89726049Sminshall printf("usage:%s remote-file\n", argv[0]); 89826049Sminshall code = -1; 89910294Ssam return; 90010294Ssam } 90110294Ssam (void) command("DELE %s", argv[1]); 90210294Ssam } 90310294Ssam 90410294Ssam /* 90511650Ssam * Delete multiple files. 90611650Ssam */ 90711650Ssam mdelete(argc, argv) 90811650Ssam char *argv[]; 90911650Ssam { 91011650Ssam char *cp; 91126049Sminshall int ointer, (*oldintr)(), mabort(); 91226049Sminshall extern jmp_buf jabort; 91311650Ssam 91411650Ssam if (argc < 2) { 91526497Sminshall (void) strcat(line, " "); 91611650Ssam printf("(remote-files) "); 91726497Sminshall (void) gets(&line[strlen(line)]); 91811650Ssam makeargv(); 91911650Ssam argc = margc; 92011650Ssam argv = margv; 92111650Ssam } 92211650Ssam if (argc < 2) { 92326049Sminshall printf("usage:%s remote-files\n", argv[0]); 92426049Sminshall code = -1; 92511650Ssam return; 92611650Ssam } 92726049Sminshall mname = argv[0]; 92826049Sminshall mflag = 1; 92926049Sminshall oldintr = signal(SIGINT, mabort); 93026049Sminshall (void) setjmp(jabort); 93126497Sminshall while ((cp = remglob(argv,0)) != NULL) { 93226049Sminshall if (*cp == '\0') { 93326049Sminshall mflag = 0; 93426049Sminshall continue; 93526049Sminshall } 93626049Sminshall if (mflag && confirm(argv[0], cp)) { 93711650Ssam (void) command("DELE %s", cp); 93826049Sminshall if (!mflag && fromatty) { 93926049Sminshall ointer = interactive; 94026049Sminshall interactive = 1; 94126049Sminshall if (confirm("Continue with", "mdelete")) { 94226049Sminshall mflag++; 94326049Sminshall } 94426049Sminshall interactive = ointer; 94526049Sminshall } 94626049Sminshall } 94726049Sminshall } 94826049Sminshall (void) signal(SIGINT, oldintr); 94926049Sminshall mflag = 0; 95011650Ssam } 95111756Ssam 95211650Ssam /* 95310294Ssam * Rename a remote file. 95410294Ssam */ 95510294Ssam renamefile(argc, argv) 95610294Ssam char *argv[]; 95710294Ssam { 95810294Ssam 95910294Ssam if (argc < 2) { 96026497Sminshall (void) strcat(line, " "); 96110294Ssam printf("(from-name) "); 96226497Sminshall (void) gets(&line[strlen(line)]); 96310294Ssam makeargv(); 96410294Ssam argc = margc; 96510294Ssam argv = margv; 96610294Ssam } 96710294Ssam if (argc < 2) { 96810294Ssam usage: 96910294Ssam printf("%s from-name to-name\n", argv[0]); 97026049Sminshall code = -1; 97110294Ssam return; 97210294Ssam } 97310294Ssam if (argc < 3) { 97426497Sminshall (void) strcat(line, " "); 97510294Ssam printf("(to-name) "); 97626497Sminshall (void) gets(&line[strlen(line)]); 97710294Ssam makeargv(); 97810294Ssam argc = margc; 97910294Ssam argv = margv; 98010294Ssam } 98110294Ssam if (argc < 3) 98210294Ssam goto usage; 98310294Ssam if (command("RNFR %s", argv[1]) == CONTINUE) 98410294Ssam (void) command("RNTO %s", argv[2]); 98510294Ssam } 98610294Ssam 98710294Ssam /* 98810294Ssam * Get a directory listing 98910294Ssam * of remote files. 99010294Ssam */ 99110294Ssam ls(argc, argv) 99210294Ssam char *argv[]; 99310294Ssam { 99411756Ssam char *cmd; 99510294Ssam 99610294Ssam if (argc < 2) 99710294Ssam argc++, argv[1] = NULL; 99810294Ssam if (argc < 3) 99910294Ssam argc++, argv[2] = "-"; 100011756Ssam if (argc > 3) { 100111756Ssam printf("usage: %s remote-directory local-file\n", argv[0]); 100226049Sminshall code = -1; 100311756Ssam return; 100411756Ssam } 100510294Ssam cmd = argv[0][0] == 'l' ? "NLST" : "LIST"; 100626049Sminshall if (strcmp(argv[2], "-") && !globulize(&argv[2])) { 100726049Sminshall code = -1; 100811353Ssam return; 100926049Sminshall } 101032344Scsvsj if (strcmp(argv[2], "-") && *argv[2] != '|') 101132344Scsvsj if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) { 101232344Scsvsj code = -1; 101332344Scsvsj return; 101432344Scsvsj } 101511756Ssam recvrequest(cmd, argv[2], argv[1], "w"); 101610294Ssam } 101710294Ssam 101810294Ssam /* 101911756Ssam * Get a directory listing 102011756Ssam * of multiple remote files. 102111756Ssam */ 102211756Ssam mls(argc, argv) 102311756Ssam char *argv[]; 102411756Ssam { 102526049Sminshall char *cmd, mode[1], *dest; 102626049Sminshall int ointer, i, (*oldintr)(), mabort(); 102726049Sminshall extern jmp_buf jabort; 102811756Ssam 102913212Ssam if (argc < 2) { 103026497Sminshall (void) strcat(line, " "); 103113212Ssam printf("(remote-files) "); 103226497Sminshall (void) gets(&line[strlen(line)]); 103313212Ssam makeargv(); 103413212Ssam argc = margc; 103513212Ssam argv = margv; 103613212Ssam } 103713212Ssam if (argc < 3) { 103826497Sminshall (void) strcat(line, " "); 103913212Ssam printf("(local-file) "); 104026497Sminshall (void) gets(&line[strlen(line)]); 104113212Ssam makeargv(); 104213212Ssam argc = margc; 104313212Ssam argv = margv; 104413212Ssam } 104513212Ssam if (argc < 3) { 104626049Sminshall printf("usage:%s remote-files local-file\n", argv[0]); 104726049Sminshall code = -1; 104813212Ssam return; 104913212Ssam } 105013212Ssam dest = argv[argc - 1]; 105113212Ssam argv[argc - 1] = NULL; 105226049Sminshall if (strcmp(dest, "-") && *dest != '|') 105326049Sminshall if (!globulize(&dest) || !confirm("output to local-file:", dest)) { 105426049Sminshall code = -1; 105513212Ssam return; 105626049Sminshall } 105711756Ssam cmd = argv[0][1] == 'l' ? "NLST" : "LIST"; 105826049Sminshall mname = argv[0]; 105926049Sminshall mflag = 1; 106026049Sminshall oldintr = signal(SIGINT, mabort); 106126049Sminshall (void) setjmp(jabort); 106226049Sminshall for (i = 1; mflag && i < argc-1; ++i) { 106326049Sminshall *mode = (i == 1) ? 'w' : 'a'; 106426049Sminshall recvrequest(cmd, dest, argv[i], mode); 106526049Sminshall if (!mflag && fromatty) { 106626049Sminshall ointer = interactive; 106726049Sminshall interactive = 1; 106826049Sminshall if (confirm("Continue with", argv[0])) { 106926049Sminshall mflag ++; 107026049Sminshall } 107126049Sminshall interactive = ointer; 107226049Sminshall } 107326049Sminshall } 107426049Sminshall (void) signal(SIGINT, oldintr); 107526049Sminshall mflag = 0; 107611756Ssam } 107711756Ssam 107811756Ssam /* 107910294Ssam * Do a shell escape 108010294Ssam */ 108126497Sminshall /*ARGSUSED*/ 108210294Ssam shell(argc, argv) 108310294Ssam char *argv[]; 108410294Ssam { 108526497Sminshall int pid, (*old1)(), (*old2)(); 108626049Sminshall char shellnam[40], *shell, *namep; 108726497Sminshall union wait status; 108810294Ssam 108911756Ssam old1 = signal (SIGINT, SIG_IGN); 109011756Ssam old2 = signal (SIGQUIT, SIG_IGN); 109111756Ssam if ((pid = fork()) == 0) { 109211756Ssam for (pid = 3; pid < 20; pid++) 109326497Sminshall (void) close(pid); 109426497Sminshall (void) signal(SIGINT, SIG_DFL); 109526497Sminshall (void) signal(SIGQUIT, SIG_DFL); 109625908Smckusick shell = getenv("SHELL"); 109725908Smckusick if (shell == NULL) 109825908Smckusick shell = "/bin/sh"; 109925908Smckusick namep = rindex(shell,'/'); 110025908Smckusick if (namep == NULL) 110125908Smckusick namep = shell; 110226497Sminshall (void) strcpy(shellnam,"-"); 110326497Sminshall (void) strcat(shellnam, ++namep); 110426049Sminshall if (strcmp(namep, "sh") != 0) 110526049Sminshall shellnam[0] = '+'; 110626049Sminshall if (debug) { 110726049Sminshall printf ("%s\n", shell); 110826497Sminshall (void) fflush (stdout); 110911756Ssam } 111026049Sminshall if (argc > 1) { 111126049Sminshall execl(shell,shellnam,"-c",altarg,(char *)0); 111226049Sminshall } 111326049Sminshall else { 111426049Sminshall execl(shell,shellnam,(char *)0); 111526049Sminshall } 111625908Smckusick perror(shell); 111726049Sminshall code = -1; 111811756Ssam exit(1); 111926049Sminshall } 112011756Ssam if (pid > 0) 112111756Ssam while (wait(&status) != pid) 112211756Ssam ; 112326497Sminshall (void) signal(SIGINT, old1); 112426497Sminshall (void) signal(SIGQUIT, old2); 112526049Sminshall if (pid == -1) { 112611756Ssam perror("Try again later"); 112726049Sminshall code = -1; 112826049Sminshall } 112926049Sminshall else { 113026049Sminshall code = 0; 113126049Sminshall } 113211756Ssam return (0); 113310294Ssam } 113410294Ssam 113510294Ssam /* 113610294Ssam * Send new user information (re-login) 113710294Ssam */ 113810294Ssam user(argc, argv) 113910294Ssam int argc; 114010294Ssam char **argv; 114110294Ssam { 114235658Sbostic char acct[80], *getpass(); 114326049Sminshall int n, aflag = 0; 114410294Ssam 114510294Ssam if (argc < 2) { 114626497Sminshall (void) strcat(line, " "); 114710294Ssam printf("(username) "); 114826497Sminshall (void) gets(&line[strlen(line)]); 114910294Ssam makeargv(); 115010294Ssam argc = margc; 115110294Ssam argv = margv; 115210294Ssam } 115310294Ssam if (argc > 4) { 115410294Ssam printf("usage: %s username [password] [account]\n", argv[0]); 115526049Sminshall code = -1; 115611756Ssam return (0); 115710294Ssam } 115810294Ssam n = command("USER %s", argv[1]); 115910294Ssam if (n == CONTINUE) { 116010294Ssam if (argc < 3 ) 116135658Sbostic argv[2] = getpass("Password: "), argc++; 116210294Ssam n = command("PASS %s", argv[2]); 116310294Ssam } 116410294Ssam if (n == CONTINUE) { 116510294Ssam if (argc < 4) { 116610294Ssam printf("Account: "); (void) fflush(stdout); 116710294Ssam (void) fgets(acct, sizeof(acct) - 1, stdin); 116810294Ssam acct[strlen(acct) - 1] = '\0'; 116910294Ssam argv[3] = acct; argc++; 117010294Ssam } 117126049Sminshall n = command("ACCT %s", argv[3]); 117226049Sminshall aflag++; 117310294Ssam } 117410294Ssam if (n != COMPLETE) { 117526497Sminshall fprintf(stdout, "Login failed.\n"); 117610294Ssam return (0); 117710294Ssam } 117826049Sminshall if (!aflag && argc == 4) { 117926049Sminshall (void) command("ACCT %s", argv[3]); 118026049Sminshall } 118110294Ssam return (1); 118210294Ssam } 118310294Ssam 118410294Ssam /* 118510294Ssam * Print working directory. 118610294Ssam */ 118710294Ssam /*VARARGS*/ 118810294Ssam pwd() 118910294Ssam { 119011756Ssam 119126049Sminshall (void) command("PWD"); 119210294Ssam } 119310294Ssam 119410294Ssam /* 119510294Ssam * Make a directory. 119610294Ssam */ 119710294Ssam makedir(argc, argv) 119810294Ssam char *argv[]; 119910294Ssam { 120010294Ssam 120110294Ssam if (argc < 2) { 120226497Sminshall (void) strcat(line, " "); 120310294Ssam printf("(directory-name) "); 120426497Sminshall (void) gets(&line[strlen(line)]); 120510294Ssam makeargv(); 120610294Ssam argc = margc; 120710294Ssam argv = margv; 120810294Ssam } 120910294Ssam if (argc < 2) { 121026049Sminshall printf("usage: %s directory-name\n", argv[0]); 121126049Sminshall code = -1; 121210294Ssam return; 121310294Ssam } 121426049Sminshall (void) command("MKD %s", argv[1]); 121510294Ssam } 121610294Ssam 121710294Ssam /* 121810294Ssam * Remove a directory. 121910294Ssam */ 122010294Ssam removedir(argc, argv) 122110294Ssam char *argv[]; 122210294Ssam { 122310294Ssam 122410294Ssam if (argc < 2) { 122526497Sminshall (void) strcat(line, " "); 122610294Ssam printf("(directory-name) "); 122726497Sminshall (void) gets(&line[strlen(line)]); 122810294Ssam makeargv(); 122910294Ssam argc = margc; 123010294Ssam argv = margv; 123110294Ssam } 123210294Ssam if (argc < 2) { 123326049Sminshall printf("usage: %s directory-name\n", argv[0]); 123426049Sminshall code = -1; 123510294Ssam return; 123610294Ssam } 123726049Sminshall (void) command("RMD %s", argv[1]); 123810294Ssam } 123910294Ssam 124010294Ssam /* 124110294Ssam * Send a line, verbatim, to the remote machine. 124210294Ssam */ 124310294Ssam quote(argc, argv) 124410294Ssam char *argv[]; 124510294Ssam { 124610294Ssam int i; 124710294Ssam char buf[BUFSIZ]; 124810294Ssam 124910294Ssam if (argc < 2) { 125026497Sminshall (void) strcat(line, " "); 125110294Ssam printf("(command line to send) "); 125226497Sminshall (void) gets(&line[strlen(line)]); 125310294Ssam makeargv(); 125410294Ssam argc = margc; 125510294Ssam argv = margv; 125610294Ssam } 125710294Ssam if (argc < 2) { 125810294Ssam printf("usage: %s line-to-send\n", argv[0]); 125926049Sminshall code = -1; 126010294Ssam return; 126110294Ssam } 126226497Sminshall (void) strcpy(buf, argv[1]); 126310294Ssam for (i = 2; i < argc; i++) { 126426497Sminshall (void) strcat(buf, " "); 126526497Sminshall (void) strcat(buf, argv[i]); 126610294Ssam } 126726049Sminshall if (command(buf) == PRELIM) { 126826049Sminshall while (getreply(0) == PRELIM); 126926049Sminshall } 127010294Ssam } 127110294Ssam 127210294Ssam /* 127310294Ssam * Ask the other side for help. 127410294Ssam */ 127510294Ssam rmthelp(argc, argv) 127610294Ssam char *argv[]; 127710294Ssam { 127810294Ssam int oldverbose = verbose; 127910294Ssam 128010294Ssam verbose = 1; 128110294Ssam (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]); 128210294Ssam verbose = oldverbose; 128310294Ssam } 128410294Ssam 128510294Ssam /* 128610294Ssam * Terminate session and exit. 128710294Ssam */ 128810294Ssam /*VARARGS*/ 128910294Ssam quit() 129010294Ssam { 129110294Ssam 129218286Sralph if (connected) 129318286Sralph disconnect(); 129426049Sminshall pswitch(1); 129526049Sminshall if (connected) { 129626049Sminshall disconnect(); 129726049Sminshall } 129810294Ssam exit(0); 129910294Ssam } 130010294Ssam 130110294Ssam /* 130210294Ssam * Terminate session, but don't exit. 130310294Ssam */ 130410294Ssam disconnect() 130510294Ssam { 130610294Ssam extern FILE *cout; 130710294Ssam extern int data; 130810294Ssam 130910294Ssam if (!connected) 131010294Ssam return; 131110294Ssam (void) command("QUIT"); 131226049Sminshall if (cout) { 131326049Sminshall (void) fclose(cout); 131426049Sminshall } 131510294Ssam cout = NULL; 131610294Ssam connected = 0; 131710294Ssam data = -1; 131826049Sminshall if (!proxy) { 131926049Sminshall macnum = 0; 132026049Sminshall } 132110294Ssam } 132211353Ssam 132311650Ssam confirm(cmd, file) 132411353Ssam char *cmd, *file; 132511353Ssam { 132611353Ssam char line[BUFSIZ]; 132711353Ssam 132811353Ssam if (!interactive) 132911650Ssam return (1); 133011353Ssam printf("%s %s? ", cmd, file); 133126497Sminshall (void) fflush(stdout); 133226497Sminshall (void) gets(line); 133311650Ssam return (*line != 'n' && *line != 'N'); 133411353Ssam } 133511353Ssam 133611353Ssam fatal(msg) 133711353Ssam char *msg; 133811353Ssam { 133911353Ssam 134026497Sminshall fprintf(stderr, "ftp: %s\n", msg); 134111353Ssam exit(1); 134211353Ssam } 134311353Ssam 134411353Ssam /* 134511353Ssam * Glob a local file name specification with 134611353Ssam * the expectation of a single return value. 134711353Ssam * Can't control multiple values being expanded 134811353Ssam * from the expression, we return only the first. 134911353Ssam */ 135011353Ssam globulize(cpp) 135111353Ssam char **cpp; 135211353Ssam { 135311353Ssam char **globbed; 135411353Ssam 135511353Ssam if (!doglob) 135611353Ssam return (1); 135711353Ssam globbed = glob(*cpp); 135811353Ssam if (globerr != NULL) { 135911353Ssam printf("%s: %s\n", *cpp, globerr); 1360*36421Sbostic if (globbed) { 136111353Ssam blkfree(globbed); 1362*36421Sbostic free(globbed); 1363*36421Sbostic } 136411353Ssam return (0); 136511353Ssam } 136611353Ssam if (globbed) { 136711353Ssam *cpp = *globbed++; 136811353Ssam /* don't waste too much memory */ 1369*36421Sbostic if (*globbed) { 137011353Ssam blkfree(globbed); 1371*36421Sbostic free(globbed); 1372*36421Sbostic } 137311353Ssam } 137411353Ssam return (1); 137511353Ssam } 137626049Sminshall 137726049Sminshall account(argc,argv) 137826049Sminshall int argc; 137926049Sminshall char **argv; 138026049Sminshall { 138135658Sbostic char acct[50], *getpass(), *ap; 138226049Sminshall 138326049Sminshall if (argc > 1) { 138426049Sminshall ++argv; 138526049Sminshall --argc; 138626049Sminshall (void) strncpy(acct,*argv,49); 138736268Sbostic acct[49] = '\0'; 138826049Sminshall while (argc > 1) { 138926049Sminshall --argc; 139026049Sminshall ++argv; 139126049Sminshall (void) strncat(acct,*argv, 49-strlen(acct)); 139226049Sminshall } 139326049Sminshall ap = acct; 139426049Sminshall } 139526049Sminshall else { 139635658Sbostic ap = getpass("Account:"); 139726049Sminshall } 139826049Sminshall (void) command("ACCT %s", ap); 139926049Sminshall } 140026049Sminshall 140126049Sminshall jmp_buf abortprox; 140226049Sminshall 140326049Sminshall proxabort() 140426049Sminshall { 140526049Sminshall extern int proxy; 140626049Sminshall 140726049Sminshall if (!proxy) { 140826049Sminshall pswitch(1); 140926049Sminshall } 141026049Sminshall if (connected) { 141126049Sminshall proxflag = 1; 141226049Sminshall } 141326049Sminshall else { 141426049Sminshall proxflag = 0; 141526049Sminshall } 141626049Sminshall pswitch(0); 141726049Sminshall longjmp(abortprox,1); 141826049Sminshall } 141926049Sminshall 142026049Sminshall doproxy(argc,argv) 142126049Sminshall int argc; 142226049Sminshall char *argv[]; 142326049Sminshall { 142426049Sminshall int (*oldintr)(), proxabort(); 142526049Sminshall register struct cmd *c; 142626049Sminshall struct cmd *getcmd(); 142726049Sminshall extern struct cmd cmdtab[]; 142826049Sminshall extern jmp_buf abortprox; 142926049Sminshall 143026049Sminshall if (argc < 2) { 143126497Sminshall (void) strcat(line, " "); 143226049Sminshall printf("(command) "); 143326497Sminshall (void) gets(&line[strlen(line)]); 143426049Sminshall makeargv(); 143526049Sminshall argc = margc; 143626049Sminshall argv = margv; 143726049Sminshall } 143826049Sminshall if (argc < 2) { 143926049Sminshall printf("usage:%s command\n", argv[0]); 144026049Sminshall code = -1; 144126049Sminshall return; 144226049Sminshall } 144326049Sminshall c = getcmd(argv[1]); 144426049Sminshall if (c == (struct cmd *) -1) { 144526049Sminshall printf("?Ambiguous command\n"); 144626497Sminshall (void) fflush(stdout); 144726049Sminshall code = -1; 144826049Sminshall return; 144926049Sminshall } 145026049Sminshall if (c == 0) { 145126049Sminshall printf("?Invalid command\n"); 145226497Sminshall (void) fflush(stdout); 145326049Sminshall code = -1; 145426049Sminshall return; 145526049Sminshall } 145626049Sminshall if (!c->c_proxy) { 145726049Sminshall printf("?Invalid proxy command\n"); 145826497Sminshall (void) fflush(stdout); 145926049Sminshall code = -1; 146026049Sminshall return; 146126049Sminshall } 146226049Sminshall if (setjmp(abortprox)) { 146326049Sminshall code = -1; 146426049Sminshall return; 146526049Sminshall } 146626049Sminshall oldintr = signal(SIGINT, proxabort); 146726049Sminshall pswitch(1); 146826049Sminshall if (c->c_conn && !connected) { 146926049Sminshall printf("Not connected\n"); 147026497Sminshall (void) fflush(stdout); 147126049Sminshall pswitch(0); 147226049Sminshall (void) signal(SIGINT, oldintr); 147326049Sminshall code = -1; 147426049Sminshall return; 147526049Sminshall } 147626049Sminshall (*c->c_handler)(argc-1, argv+1); 147726049Sminshall if (connected) { 147826049Sminshall proxflag = 1; 147926049Sminshall } 148026049Sminshall else { 148126049Sminshall proxflag = 0; 148226049Sminshall } 148326049Sminshall pswitch(0); 148426049Sminshall (void) signal(SIGINT, oldintr); 148526049Sminshall } 148626049Sminshall 148726049Sminshall setcase() 148826049Sminshall { 148926049Sminshall mcase = !mcase; 149026049Sminshall printf("Case mapping %s.\n", onoff(mcase)); 149126049Sminshall code = mcase; 149226049Sminshall } 149326049Sminshall 149426049Sminshall setcr() 149526049Sminshall { 149626049Sminshall crflag = !crflag; 149726049Sminshall printf("Carriage Return stripping %s.\n", onoff(crflag)); 149826049Sminshall code = crflag; 149926049Sminshall } 150026049Sminshall 150126049Sminshall setntrans(argc,argv) 150226049Sminshall int argc; 150326049Sminshall char *argv[]; 150426049Sminshall { 150526049Sminshall if (argc == 1) { 150626049Sminshall ntflag = 0; 150726049Sminshall printf("Ntrans off.\n"); 150826049Sminshall code = ntflag; 150926049Sminshall return; 151026049Sminshall } 151126049Sminshall ntflag++; 151226049Sminshall code = ntflag; 151326049Sminshall (void) strncpy(ntin, argv[1], 16); 151426049Sminshall ntin[16] = '\0'; 151526049Sminshall if (argc == 2) { 151626049Sminshall ntout[0] = '\0'; 151726049Sminshall return; 151826049Sminshall } 151926049Sminshall (void) strncpy(ntout, argv[2], 16); 152026049Sminshall ntout[16] = '\0'; 152126049Sminshall } 152226049Sminshall 152326049Sminshall char * 152426049Sminshall dotrans(name) 152526049Sminshall char *name; 152626049Sminshall { 152726049Sminshall static char new[MAXPATHLEN]; 152826049Sminshall char *cp1, *cp2 = new; 152926049Sminshall register int i, ostop, found; 153026049Sminshall 153126049Sminshall for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++); 153226049Sminshall for (cp1 = name; *cp1; cp1++) { 153326049Sminshall found = 0; 153426049Sminshall for (i = 0; *(ntin + i) && i < 16; i++) { 153526049Sminshall if (*cp1 == *(ntin + i)) { 153626049Sminshall found++; 153726049Sminshall if (i < ostop) { 153826049Sminshall *cp2++ = *(ntout + i); 153926049Sminshall } 154026049Sminshall break; 154126049Sminshall } 154226049Sminshall } 154326049Sminshall if (!found) { 154426049Sminshall *cp2++ = *cp1; 154526049Sminshall } 154626049Sminshall } 154726049Sminshall *cp2 = '\0'; 154826049Sminshall return(new); 154926049Sminshall } 155026049Sminshall 155126049Sminshall setnmap(argc, argv) 155226049Sminshall int argc; 155326049Sminshall char *argv[]; 155426049Sminshall { 155526049Sminshall char *cp; 155626049Sminshall 155726049Sminshall if (argc == 1) { 155826049Sminshall mapflag = 0; 155926049Sminshall printf("Nmap off.\n"); 156026049Sminshall code = mapflag; 156126049Sminshall return; 156226049Sminshall } 156326049Sminshall if (argc < 3) { 156426497Sminshall (void) strcat(line, " "); 156526049Sminshall printf("(mapout) "); 156626497Sminshall (void) gets(&line[strlen(line)]); 156726049Sminshall makeargv(); 156826049Sminshall argc = margc; 156926049Sminshall argv = margv; 157026049Sminshall } 157126049Sminshall if (argc < 3) { 157226049Sminshall printf("Usage: %s [mapin mapout]\n",argv[0]); 157326049Sminshall code = -1; 157426049Sminshall return; 157526049Sminshall } 157626049Sminshall mapflag = 1; 157726049Sminshall code = 1; 157826049Sminshall cp = index(altarg, ' '); 157926049Sminshall if (proxy) { 158026049Sminshall while(*++cp == ' '); 158126049Sminshall altarg = cp; 158226049Sminshall cp = index(altarg, ' '); 158326049Sminshall } 158426049Sminshall *cp = '\0'; 158526049Sminshall (void) strncpy(mapin, altarg, MAXPATHLEN - 1); 158626049Sminshall while (*++cp == ' '); 158726049Sminshall (void) strncpy(mapout, cp, MAXPATHLEN - 1); 158826049Sminshall } 158926049Sminshall 159026049Sminshall char * 159126049Sminshall domap(name) 159226049Sminshall char *name; 159326049Sminshall { 159426049Sminshall static char new[MAXPATHLEN]; 159526049Sminshall register char *cp1 = name, *cp2 = mapin; 159626049Sminshall char *tp[9], *te[9]; 159726049Sminshall int i, toks[9], toknum, match = 1; 159826049Sminshall 159926049Sminshall for (i=0; i < 9; ++i) { 160026049Sminshall toks[i] = 0; 160126049Sminshall } 160226049Sminshall while (match && *cp1 && *cp2) { 160326049Sminshall switch (*cp2) { 160426049Sminshall case '\\': 160526049Sminshall if (*++cp2 != *cp1) { 160626049Sminshall match = 0; 160726049Sminshall } 160826049Sminshall break; 160926049Sminshall case '$': 161026049Sminshall if (*(cp2+1) >= '1' && (*cp2+1) <= '9') { 161126049Sminshall if (*cp1 != *(++cp2+1)) { 161226049Sminshall toks[toknum = *cp2 - '1']++; 161326049Sminshall tp[toknum] = cp1; 161426049Sminshall while (*++cp1 && *(cp2+1) 161526049Sminshall != *cp1); 161626049Sminshall te[toknum] = cp1; 161726049Sminshall } 161826049Sminshall cp2++; 161926049Sminshall break; 162026049Sminshall } 162126049Sminshall /* intentional drop through */ 162226049Sminshall default: 162326049Sminshall if (*cp2 != *cp1) { 162426049Sminshall match = 0; 162526049Sminshall } 162626049Sminshall break; 162726049Sminshall } 162826049Sminshall if (*cp1) { 162926049Sminshall cp1++; 163026049Sminshall } 163126049Sminshall if (*cp2) { 163226049Sminshall cp2++; 163326049Sminshall } 163426049Sminshall } 163526049Sminshall cp1 = new; 163626049Sminshall *cp1 = '\0'; 163726049Sminshall cp2 = mapout; 163826049Sminshall while (*cp2) { 163926049Sminshall match = 0; 164026049Sminshall switch (*cp2) { 164126049Sminshall case '\\': 164226049Sminshall if (*(cp2 + 1)) { 164326049Sminshall *cp1++ = *++cp2; 164426049Sminshall } 164526049Sminshall break; 164626049Sminshall case '[': 164726049Sminshall LOOP: 164826049Sminshall if (*++cp2 == '$' && isdigit(*(cp2+1))) { 164926049Sminshall if (*++cp2 == '0') { 165026049Sminshall char *cp3 = name; 165126049Sminshall 165226049Sminshall while (*cp3) { 165326049Sminshall *cp1++ = *cp3++; 165426049Sminshall } 165526049Sminshall match = 1; 165626049Sminshall } 165726049Sminshall else if (toks[toknum = *cp2 - '1']) { 165826049Sminshall char *cp3 = tp[toknum]; 165926049Sminshall 166026049Sminshall while (cp3 != te[toknum]) { 166126049Sminshall *cp1++ = *cp3++; 166226049Sminshall } 166326049Sminshall match = 1; 166426049Sminshall } 166526049Sminshall } 166626049Sminshall else { 166726049Sminshall while (*cp2 && *cp2 != ',' && 166826049Sminshall *cp2 != ']') { 166926049Sminshall if (*cp2 == '\\') { 167026049Sminshall cp2++; 167126049Sminshall } 167226049Sminshall else if (*cp2 == '$' && 167326049Sminshall isdigit(*(cp2+1))) { 167426049Sminshall if (*++cp2 == '0') { 167526049Sminshall char *cp3 = name; 167626049Sminshall 167726049Sminshall while (*cp3) { 167826049Sminshall *cp1++ = *cp3++; 167926049Sminshall } 168026049Sminshall } 168126049Sminshall else if (toks[toknum = 168226049Sminshall *cp2 - '1']) { 168326049Sminshall char *cp3=tp[toknum]; 168426049Sminshall 168526049Sminshall while (cp3 != 168626049Sminshall te[toknum]) { 168726049Sminshall *cp1++ = *cp3++; 168826049Sminshall } 168926049Sminshall } 169026049Sminshall } 169126049Sminshall else if (*cp2) { 169226049Sminshall *cp1++ = *cp2++; 169326049Sminshall } 169426049Sminshall } 169526049Sminshall if (!*cp2) { 169626049Sminshall printf("nmap: unbalanced brackets\n"); 169726049Sminshall return(name); 169826049Sminshall } 169926049Sminshall match = 1; 170026049Sminshall cp2--; 170126049Sminshall } 170226049Sminshall if (match) { 170326049Sminshall while (*++cp2 && *cp2 != ']') { 170426049Sminshall if (*cp2 == '\\' && *(cp2 + 1)) { 170526049Sminshall cp2++; 170626049Sminshall } 170726049Sminshall } 170826049Sminshall if (!*cp2) { 170926049Sminshall printf("nmap: unbalanced brackets\n"); 171026049Sminshall return(name); 171126049Sminshall } 171226049Sminshall break; 171326049Sminshall } 171426049Sminshall switch (*++cp2) { 171526049Sminshall case ',': 171626049Sminshall goto LOOP; 171726049Sminshall case ']': 171826049Sminshall break; 171926049Sminshall default: 172026049Sminshall cp2--; 172126049Sminshall goto LOOP; 172226049Sminshall } 172326049Sminshall break; 172426049Sminshall case '$': 172526049Sminshall if (isdigit(*(cp2 + 1))) { 172626049Sminshall if (*++cp2 == '0') { 172726049Sminshall char *cp3 = name; 172826049Sminshall 172926049Sminshall while (*cp3) { 173026049Sminshall *cp1++ = *cp3++; 173126049Sminshall } 173226049Sminshall } 173326049Sminshall else if (toks[toknum = *cp2 - '1']) { 173426049Sminshall char *cp3 = tp[toknum]; 173526049Sminshall 173626049Sminshall while (cp3 != te[toknum]) { 173726049Sminshall *cp1++ = *cp3++; 173826049Sminshall } 173926049Sminshall } 174026049Sminshall break; 174126049Sminshall } 174226049Sminshall /* intentional drop through */ 174326049Sminshall default: 174426049Sminshall *cp1++ = *cp2; 174526049Sminshall break; 174626049Sminshall } 174726049Sminshall cp2++; 174826049Sminshall } 174926049Sminshall *cp1 = '\0'; 175026049Sminshall if (!*new) { 175126049Sminshall return(name); 175226049Sminshall } 175326049Sminshall return(new); 175426049Sminshall } 175526049Sminshall 175626049Sminshall setsunique() 175726049Sminshall { 175826049Sminshall sunique = !sunique; 175926049Sminshall printf("Store unique %s.\n", onoff(sunique)); 176026049Sminshall code = sunique; 176126049Sminshall } 176226049Sminshall 176326049Sminshall setrunique() 176426049Sminshall { 176526049Sminshall runique = !runique; 176626049Sminshall printf("Receive unique %s.\n", onoff(runique)); 176726049Sminshall code = runique; 176826049Sminshall } 176926049Sminshall 177026049Sminshall /* change directory to perent directory */ 177126049Sminshall cdup() 177226049Sminshall { 177326049Sminshall (void) command("CDUP"); 177426049Sminshall } 177526049Sminshall 177626049Sminshall macdef(argc, argv) 177726049Sminshall int argc; 177826049Sminshall char *argv[]; 177926049Sminshall { 178026049Sminshall char *tmp; 178126049Sminshall int c; 178226049Sminshall 178326049Sminshall if (macnum == 16) { 178426049Sminshall printf("Limit of 16 macros have already been defined\n"); 178526049Sminshall code = -1; 178626049Sminshall return; 178726049Sminshall } 178826049Sminshall if (argc < 2) { 178926497Sminshall (void) strcat(line, " "); 179026049Sminshall printf("(macro name) "); 179126497Sminshall (void) gets(&line[strlen(line)]); 179226049Sminshall makeargv(); 179326049Sminshall argc = margc; 179426049Sminshall argv = margv; 179526049Sminshall } 179626049Sminshall if (argc != 2) { 179726049Sminshall printf("Usage: %s macro_name\n",argv[0]); 179826049Sminshall code = -1; 179926049Sminshall return; 180026049Sminshall } 180126049Sminshall if (interactive) { 180226049Sminshall printf("Enter macro line by line, terminating it with a null line\n"); 180326049Sminshall } 180426497Sminshall (void) strncpy(macros[macnum].mac_name, argv[1], 8); 180526049Sminshall if (macnum == 0) { 180626049Sminshall macros[macnum].mac_start = macbuf; 180726049Sminshall } 180826049Sminshall else { 180926049Sminshall macros[macnum].mac_start = macros[macnum - 1].mac_end + 1; 181026049Sminshall } 181126049Sminshall tmp = macros[macnum].mac_start; 181226049Sminshall while (tmp != macbuf+4096) { 181326049Sminshall if ((c = getchar()) == EOF) { 181426049Sminshall printf("macdef:end of file encountered\n"); 181526049Sminshall code = -1; 181626049Sminshall return; 181726049Sminshall } 181826049Sminshall if ((*tmp = c) == '\n') { 181926049Sminshall if (tmp == macros[macnum].mac_start) { 182026049Sminshall macros[macnum++].mac_end = tmp; 182126049Sminshall code = 0; 182226049Sminshall return; 182326049Sminshall } 182426049Sminshall if (*(tmp-1) == '\0') { 182526049Sminshall macros[macnum++].mac_end = tmp - 1; 182626049Sminshall code = 0; 182726049Sminshall return; 182826049Sminshall } 182926049Sminshall *tmp = '\0'; 183026049Sminshall } 183126049Sminshall tmp++; 183226049Sminshall } 183326049Sminshall while (1) { 183426049Sminshall while ((c = getchar()) != '\n' && c != EOF); 183526049Sminshall if (c == EOF || getchar() == '\n') { 183626049Sminshall printf("Macro not defined - 4k buffer exceeded\n"); 183726049Sminshall code = -1; 183826049Sminshall return; 183926049Sminshall } 184026049Sminshall } 184126049Sminshall } 1842