121737Sdist /* 236942Skarels * Copyright (c) 1985, 1989 Regents of the University of California. 333737Sbostic * All rights reserved. 433737Sbostic * 533737Sbostic * Redistribution and use in source and binary forms are permitted 634901Sbostic * provided that the above copyright notice and this paragraph are 734901Sbostic * duplicated in all such forms and that any documentation, 834901Sbostic * advertising materials, and other materials related to such 934901Sbostic * distribution and use acknowledge that the software was developed 1034901Sbostic * by the University of California, Berkeley. The name of the 1134901Sbostic * University may not be used to endorse or promote products derived 1234901Sbostic * from this software without specific prior written permission. 1334901Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434901Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1536935Skarels * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621737Sdist */ 1721737Sdist 1810294Ssam #ifndef lint 19*38032Skarels static char sccsid[] = "@(#)cmds.c 5.19 (Berkeley) 05/17/89"; 2033737Sbostic #endif /* not lint */ 2110294Ssam 2210294Ssam /* 2310294Ssam * FTP User Program -- Command Routines. 2410294Ssam */ 2536940Skarels #include <sys/param.h> 2636940Skarels #include <sys/wait.h> 2736940Skarels #include <sys/stat.h> 2810294Ssam #include <sys/socket.h> 2910294Ssam 3012396Ssam #include <arpa/ftp.h> 3112396Ssam 3210294Ssam #include <signal.h> 3310294Ssam #include <stdio.h> 3410294Ssam #include <errno.h> 3510294Ssam #include <netdb.h> 3626049Sminshall #include <ctype.h> 3736935Skarels #include <time.h> 3810294Ssam 3936940Skarels #include "ftp_var.h" 4037458Skarels #include "pathnames.h" 4110294Ssam 4211353Ssam extern char *globerr; 4311353Ssam extern char **glob(); 4411756Ssam extern char *home; 4511756Ssam extern char *remglob(); 4611756Ssam extern char *getenv(); 4711756Ssam extern char *index(); 4811756Ssam extern char *rindex(); 4937224Skarels extern off_t restart_point; 5036935Skarels extern char reply_string[]; 5136935Skarels 5226049Sminshall char *mname; 5326049Sminshall jmp_buf jabort; 5426049Sminshall char *dotrans(), *domap(); 5510294Ssam 5610294Ssam /* 5710294Ssam * Connect to peer server and 5810294Ssam * auto-login, if possible. 5910294Ssam */ 6010294Ssam setpeer(argc, argv) 6110294Ssam int argc; 6210294Ssam char *argv[]; 6310294Ssam { 6425903Skarels char *host, *hookup(); 6510294Ssam int port; 6610294Ssam 6710294Ssam if (connected) { 6826049Sminshall printf("Already connected to %s, use close first.\n", 6910294Ssam hostname); 7026049Sminshall code = -1; 7110294Ssam return; 7210294Ssam } 7310294Ssam if (argc < 2) { 7426497Sminshall (void) strcat(line, " "); 7510294Ssam printf("(to) "); 7626497Sminshall (void) gets(&line[strlen(line)]); 7710294Ssam makeargv(); 7810294Ssam argc = margc; 7910294Ssam argv = margv; 8010294Ssam } 8110294Ssam if (argc > 3) { 8210294Ssam printf("usage: %s host-name [port]\n", argv[0]); 8326049Sminshall code = -1; 8410294Ssam return; 8510294Ssam } 8610294Ssam port = sp->s_port; 8710294Ssam if (argc > 2) { 8811218Ssam port = atoi(argv[2]); 8910294Ssam if (port <= 0) { 9011218Ssam printf("%s: bad port number-- %s\n", argv[1], argv[2]); 9111218Ssam printf ("usage: %s host-name [port]\n", argv[0]); 9226049Sminshall code = -1; 9310294Ssam return; 9410294Ssam } 9510294Ssam port = htons(port); 9610294Ssam } 9710294Ssam host = hookup(argv[1], port); 9810294Ssam if (host) { 9937228Skarels int overbose; 10037228Skarels 10110294Ssam connected = 1; 102*38032Skarels /* 103*38032Skarels * Set up defaults for FTP. 104*38032Skarels */ 105*38032Skarels (void) strcpy(typename, "ascii"), type = TYPE_A; 106*38032Skarels curtype = TYPE_A; 107*38032Skarels (void) strcpy(formname, "non-print"), form = FORM_N; 108*38032Skarels (void) strcpy(modename, "stream"), mode = MODE_S; 109*38032Skarels (void) strcpy(structname, "file"), stru = STRU_F; 110*38032Skarels (void) strcpy(bytename, "8"), bytesize = 8; 11137228Skarels if (autologin) 11237228Skarels (void) login(argv[1]); 11336940Skarels 11436935Skarels #if defined(unix) && NBBY == 8 11536935Skarels /* 11636935Skarels * this ifdef is to keep someone form "porting" this to an incompatible 11736935Skarels * system and not checking this out. This way they have to think about it. 11836935Skarels */ 11937228Skarels overbose = verbose; 12037228Skarels if (debug == 0) 12137228Skarels verbose = -1; 12237228Skarels if (command("SYST") == COMPLETE && overbose) { 12337228Skarels register char *cp, c; 12437228Skarels cp = index(reply_string+4, ' '); 12537228Skarels if (cp == NULL) 12637228Skarels cp = index(reply_string+4, '\r'); 12737228Skarels if (cp) { 12837228Skarels if (cp[-1] == '.') 12937228Skarels cp--; 13037228Skarels c = *cp; 13137228Skarels *cp = '\0'; 13237228Skarels } 13336935Skarels 13437228Skarels printf("Remote system type is %s.\n", 13537228Skarels reply_string+4); 13637228Skarels if (cp) 13737228Skarels *cp = c; 13837228Skarels } 13937228Skarels if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) { 140*38032Skarels if (proxy) 141*38032Skarels unix_proxy = 1; 142*38032Skarels else 143*38032Skarels unix_server = 1; 144*38032Skarels /* 145*38032Skarels * Set type to 0 (not specified by user), 146*38032Skarels * meaning binary by default, but don't bother 147*38032Skarels * telling server. We can use binary 148*38032Skarels * for text files unless changed by the user. 149*38032Skarels */ 150*38032Skarels type = 0; 151*38032Skarels (void) strcpy(typename, "binary"); 15237228Skarels if (overbose) 15337228Skarels printf("Using %s mode to transfer files.\n", 15437228Skarels typename); 155*38032Skarels } else { 156*38032Skarels if (proxy) 157*38032Skarels unix_proxy = 0; 158*38032Skarels else 159*38032Skarels unix_server = 0; 160*38032Skarels if (overbose && 161*38032Skarels !strncmp(reply_string, "215 TOPS20", 10)) 162*38032Skarels printf( 16336940Skarels "Remember to set tenex mode when transfering binary files from this machine.\n"); 16437228Skarels } 16537228Skarels verbose = overbose; 16636935Skarels #endif /* unix */ 16710294Ssam } 16810294Ssam } 16910294Ssam 17010294Ssam struct types { 17110294Ssam char *t_name; 17210294Ssam char *t_mode; 17310294Ssam int t_type; 17411218Ssam char *t_arg; 17510294Ssam } types[] = { 17611218Ssam { "ascii", "A", TYPE_A, 0 }, 17711218Ssam { "binary", "I", TYPE_I, 0 }, 17811218Ssam { "image", "I", TYPE_I, 0 }, 17911218Ssam { "ebcdic", "E", TYPE_E, 0 }, 18011218Ssam { "tenex", "L", TYPE_L, bytename }, 18110294Ssam 0 18210294Ssam }; 18310294Ssam 18410294Ssam /* 18510294Ssam * Set transfer type. 18610294Ssam */ 18710294Ssam settype(argc, argv) 18810294Ssam char *argv[]; 18910294Ssam { 19010294Ssam register struct types *p; 19111218Ssam int comret; 19210294Ssam 19310294Ssam if (argc > 2) { 19410294Ssam char *sep; 19510294Ssam 19610294Ssam printf("usage: %s [", argv[0]); 19710294Ssam sep = " "; 19810294Ssam for (p = types; p->t_name; p++) { 19910294Ssam printf("%s%s", sep, p->t_name); 200*38032Skarels sep = " | "; 20110294Ssam } 20210294Ssam printf(" ]\n"); 20326049Sminshall code = -1; 20410294Ssam return; 20510294Ssam } 20610294Ssam if (argc < 2) { 20710294Ssam printf("Using %s mode to transfer files.\n", typename); 20826049Sminshall code = 0; 20910294Ssam return; 21010294Ssam } 21110294Ssam for (p = types; p->t_name; p++) 21210294Ssam if (strcmp(argv[1], p->t_name) == 0) 21310294Ssam break; 21410294Ssam if (p->t_name == 0) { 21510294Ssam printf("%s: unknown mode\n", argv[1]); 21626049Sminshall code = -1; 21710294Ssam return; 21810294Ssam } 21911218Ssam if ((p->t_arg != NULL) && (*(p->t_arg) != '\0')) 22011218Ssam comret = command ("TYPE %s %s", p->t_mode, p->t_arg); 22111218Ssam else 22211218Ssam comret = command("TYPE %s", p->t_mode); 22311218Ssam if (comret == COMPLETE) { 22426497Sminshall (void) strcpy(typename, p->t_name); 225*38032Skarels curtype = type = p->t_type; 22610294Ssam } 22710294Ssam } 22810294Ssam 22910294Ssam /* 230*38032Skarels * Internal form of settype; changes current type in use with server 231*38032Skarels * without changing our notion of the type for data transfers. 232*38032Skarels * Used to change to and from ascii for listings. 233*38032Skarels */ 234*38032Skarels changetype(newtype, show) 235*38032Skarels int newtype, show; 236*38032Skarels { 237*38032Skarels register struct types *p; 238*38032Skarels int comret, oldverbose = verbose; 239*38032Skarels 240*38032Skarels if (newtype == 0) 241*38032Skarels newtype = TYPE_I; 242*38032Skarels if (newtype == curtype) 243*38032Skarels return; 244*38032Skarels if (debug == 0 && show == 0) 245*38032Skarels verbose = 0; 246*38032Skarels for (p = types; p->t_name; p++) 247*38032Skarels if (newtype == p->t_type) 248*38032Skarels break; 249*38032Skarels if (p->t_name == 0) { 250*38032Skarels printf("ftp: internal error: unknown type %d\n", newtype); 251*38032Skarels return; 252*38032Skarels } 253*38032Skarels if (newtype == TYPE_L && bytename[0] != '\0') 254*38032Skarels comret = command("TYPE %s %s", p->t_mode, bytename); 255*38032Skarels else 256*38032Skarels comret = command("TYPE %s", p->t_mode); 257*38032Skarels if (comret == COMPLETE) 258*38032Skarels curtype = newtype; 259*38032Skarels verbose = oldverbose; 260*38032Skarels } 261*38032Skarels 262*38032Skarels /* 26310294Ssam * Set binary transfer type. 26410294Ssam */ 26510294Ssam /*VARARGS*/ 26610294Ssam setbinary() 26710294Ssam { 26810294Ssam 26910294Ssam call(settype, "type", "binary", 0); 27010294Ssam } 27110294Ssam 27210294Ssam /* 27310294Ssam * Set ascii transfer type. 27410294Ssam */ 27510294Ssam /*VARARGS*/ 27610294Ssam setascii() 27710294Ssam { 27810294Ssam 27910294Ssam call(settype, "type", "ascii", 0); 28010294Ssam } 28110294Ssam 28210294Ssam /* 28310294Ssam * Set tenex transfer type. 28410294Ssam */ 28510294Ssam /*VARARGS*/ 28610294Ssam settenex() 28710294Ssam { 28810294Ssam 28910294Ssam call(settype, "type", "tenex", 0); 29010294Ssam } 29110294Ssam 29210294Ssam /* 29310294Ssam * Set ebcdic transfer type. 29410294Ssam */ 29510294Ssam /*VARARGS*/ 29610294Ssam setebcdic() 29710294Ssam { 29810294Ssam 29910294Ssam call(settype, "type", "ebcdic", 0); 30010294Ssam } 30110294Ssam 30210294Ssam /* 30310294Ssam * Set file transfer mode. 30410294Ssam */ 30526497Sminshall /*ARGSUSED*/ 30610294Ssam setmode(argc, argv) 30710294Ssam char *argv[]; 30810294Ssam { 30910294Ssam 31010294Ssam printf("We only support %s mode, sorry.\n", modename); 31126049Sminshall code = -1; 31210294Ssam } 31310294Ssam 31410294Ssam /* 31510294Ssam * Set file transfer format. 31610294Ssam */ 31726497Sminshall /*ARGSUSED*/ 31810294Ssam setform(argc, argv) 31910294Ssam char *argv[]; 32010294Ssam { 32110294Ssam 32210294Ssam printf("We only support %s format, sorry.\n", formname); 32326049Sminshall code = -1; 32410294Ssam } 32510294Ssam 32610294Ssam /* 32710294Ssam * Set file transfer structure. 32810294Ssam */ 32926497Sminshall /*ARGSUSED*/ 33010294Ssam setstruct(argc, argv) 33110294Ssam char *argv[]; 33210294Ssam { 33310294Ssam 33410294Ssam printf("We only support %s structure, sorry.\n", structname); 33526049Sminshall code = -1; 33610294Ssam } 33710294Ssam 33818286Sralph /* 33918286Sralph * Send a single file. 34018286Sralph */ 34110294Ssam put(argc, argv) 34211756Ssam int argc; 34310294Ssam char *argv[]; 34410294Ssam { 34511650Ssam char *cmd; 34626049Sminshall int loc = 0; 34737225Skarels char *oldargv1, *oldargv2; 34811650Ssam 34926049Sminshall if (argc == 2) { 35026049Sminshall argc++; 35126049Sminshall argv[2] = argv[1]; 35226049Sminshall loc++; 35326049Sminshall } 35410294Ssam if (argc < 2) { 35526497Sminshall (void) strcat(line, " "); 35610294Ssam printf("(local-file) "); 35726497Sminshall (void) gets(&line[strlen(line)]); 35810294Ssam makeargv(); 35910294Ssam argc = margc; 36010294Ssam argv = margv; 36110294Ssam } 36210294Ssam if (argc < 2) { 36310294Ssam usage: 36426049Sminshall printf("usage:%s local-file remote-file\n", argv[0]); 36526049Sminshall code = -1; 36610294Ssam return; 36710294Ssam } 36810294Ssam if (argc < 3) { 36926497Sminshall (void) strcat(line, " "); 37010294Ssam printf("(remote-file) "); 37126497Sminshall (void) gets(&line[strlen(line)]); 37210294Ssam makeargv(); 37310294Ssam argc = margc; 37410294Ssam argv = margv; 37510294Ssam } 37610294Ssam if (argc < 3) 37710294Ssam goto usage; 37825908Smckusick oldargv1 = argv[1]; 37937225Skarels oldargv2 = argv[2]; 38026049Sminshall if (!globulize(&argv[1])) { 38126049Sminshall code = -1; 38211353Ssam return; 38326049Sminshall } 38425908Smckusick /* 38525908Smckusick * If "globulize" modifies argv[1], and argv[2] is a copy of 38625908Smckusick * the old argv[1], make it a copy of the new argv[1]. 38725908Smckusick */ 38826049Sminshall if (argv[1] != oldargv1 && argv[2] == oldargv1) { 38925908Smckusick argv[2] = argv[1]; 39026049Sminshall } 39126049Sminshall cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR"); 39226049Sminshall if (loc && ntflag) { 39326049Sminshall argv[2] = dotrans(argv[2]); 39426049Sminshall } 39526049Sminshall if (loc && mapflag) { 39626049Sminshall argv[2] = domap(argv[2]); 39726049Sminshall } 39837225Skarels sendrequest(cmd, argv[1], argv[2], 39937225Skarels argv[1] != oldargv1 || argv[2] != oldargv2); 40010294Ssam } 40110294Ssam 40210294Ssam /* 40311756Ssam * Send multiple files. 40410294Ssam */ 40511353Ssam mput(argc, argv) 40611353Ssam char *argv[]; 40711353Ssam { 40813212Ssam register int i; 40926049Sminshall int ointer, (*oldintr)(), mabort(); 41026049Sminshall extern jmp_buf jabort; 41126049Sminshall char *tp; 41211353Ssam 41311650Ssam if (argc < 2) { 41426497Sminshall (void) strcat(line, " "); 41511650Ssam printf("(local-files) "); 41626497Sminshall (void) gets(&line[strlen(line)]); 41711650Ssam makeargv(); 41811650Ssam argc = margc; 41911650Ssam argv = margv; 42011353Ssam } 42111353Ssam if (argc < 2) { 42226049Sminshall printf("usage:%s local-files\n", argv[0]); 42326049Sminshall code = -1; 42411353Ssam return; 42511353Ssam } 42626049Sminshall mname = argv[0]; 42726049Sminshall mflag = 1; 42826049Sminshall oldintr = signal(SIGINT, mabort); 42926049Sminshall (void) setjmp(jabort); 43026049Sminshall if (proxy) { 43126049Sminshall char *cp, *tp2, tmpbuf[MAXPATHLEN]; 43226049Sminshall 43326497Sminshall while ((cp = remglob(argv,0)) != NULL) { 43426049Sminshall if (*cp == 0) { 43526049Sminshall mflag = 0; 43626049Sminshall continue; 43726049Sminshall } 43826049Sminshall if (mflag && confirm(argv[0], cp)) { 43926049Sminshall tp = cp; 44026049Sminshall if (mcase) { 44126049Sminshall while (*tp && !islower(*tp)) { 44226049Sminshall tp++; 44326049Sminshall } 44426049Sminshall if (!*tp) { 44526049Sminshall tp = cp; 44626049Sminshall tp2 = tmpbuf; 44726049Sminshall while ((*tp2 = *tp) != NULL) { 44826049Sminshall if (isupper(*tp2)) { 44926049Sminshall *tp2 = 'a' + *tp2 - 'A'; 45026049Sminshall } 45126049Sminshall tp++; 45226049Sminshall tp2++; 45326049Sminshall } 45426049Sminshall } 45526049Sminshall tp = tmpbuf; 45626049Sminshall } 45726049Sminshall if (ntflag) { 45826049Sminshall tp = dotrans(tp); 45926049Sminshall } 46026049Sminshall if (mapflag) { 46126049Sminshall tp = domap(tp); 46226049Sminshall } 46337225Skarels sendrequest((sunique) ? "STOU" : "STOR", 46437225Skarels cp, tp, cp != tp || !interactive); 46526049Sminshall if (!mflag && fromatty) { 46626049Sminshall ointer = interactive; 46726049Sminshall interactive = 1; 46826049Sminshall if (confirm("Continue with","mput")) { 46926049Sminshall mflag++; 47026049Sminshall } 47126049Sminshall interactive = ointer; 47226049Sminshall } 47326049Sminshall } 47426049Sminshall } 47526049Sminshall (void) signal(SIGINT, oldintr); 47626049Sminshall mflag = 0; 47726049Sminshall return; 47826049Sminshall } 47913212Ssam for (i = 1; i < argc; i++) { 48013212Ssam register char **cpp, **gargs; 48113212Ssam 48213212Ssam if (!doglob) { 48326049Sminshall if (mflag && confirm(argv[0], argv[i])) { 48426049Sminshall tp = (ntflag) ? dotrans(argv[i]) : argv[i]; 48526049Sminshall tp = (mapflag) ? domap(tp) : tp; 48626049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 48737225Skarels argv[i], tp, tp != argv[i] || !interactive); 48826049Sminshall if (!mflag && fromatty) { 48926049Sminshall ointer = interactive; 49026049Sminshall interactive = 1; 49126049Sminshall if (confirm("Continue with","mput")) { 49226049Sminshall mflag++; 49326049Sminshall } 49426049Sminshall interactive = ointer; 49526049Sminshall } 49626049Sminshall } 49713212Ssam continue; 49813212Ssam } 49913212Ssam gargs = glob(argv[i]); 50011650Ssam if (globerr != NULL) { 50111650Ssam printf("%s\n", globerr); 50236421Sbostic if (gargs) { 50311650Ssam blkfree(gargs); 50436421Sbostic free(gargs); 50536421Sbostic } 50613212Ssam continue; 50711353Ssam } 50826049Sminshall for (cpp = gargs; cpp && *cpp != NULL; cpp++) { 50926049Sminshall if (mflag && confirm(argv[0], *cpp)) { 51026049Sminshall tp = (ntflag) ? dotrans(*cpp) : *cpp; 51126049Sminshall tp = (mapflag) ? domap(tp) : tp; 51226049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 51337225Skarels *cpp, tp, *cpp != tp || !interactive); 51426049Sminshall if (!mflag && fromatty) { 51526049Sminshall ointer = interactive; 51626049Sminshall interactive = 1; 51726049Sminshall if (confirm("Continue with","mput")) { 51826049Sminshall mflag++; 51926049Sminshall } 52026049Sminshall interactive = ointer; 52126049Sminshall } 52226049Sminshall } 52326049Sminshall } 52436421Sbostic if (gargs != NULL) { 52513212Ssam blkfree(gargs); 52636421Sbostic free(gargs); 52736421Sbostic } 52811353Ssam } 52926049Sminshall (void) signal(SIGINT, oldintr); 53026049Sminshall mflag = 0; 53111353Ssam } 53211353Ssam 53337224Skarels reget(argc, argv) 53437224Skarels char *argv[]; 53537224Skarels { 53637224Skarels (void) getit(argc, argv, 1, "r+w"); 53737224Skarels } 53836935Skarels 53937224Skarels get(argc, argv) 54037224Skarels char *argv[]; 54137224Skarels { 54237224Skarels (void) getit(argc, argv, 0, restart_point ? "r+w" : "w" ); 54337224Skarels } 54437224Skarels 54511353Ssam /* 54611353Ssam * Receive one file. 54711353Ssam */ 54837224Skarels getit(argc, argv, restartit, mode) 54910294Ssam char *argv[]; 55037224Skarels char *mode; 55110294Ssam { 55226049Sminshall int loc = 0; 55337225Skarels char *oldargv1, *oldargv2; 55410294Ssam 55526049Sminshall if (argc == 2) { 55626049Sminshall argc++; 55726049Sminshall argv[2] = argv[1]; 55826049Sminshall loc++; 55926049Sminshall } 56010294Ssam if (argc < 2) { 56126497Sminshall (void) strcat(line, " "); 56210294Ssam printf("(remote-file) "); 56326497Sminshall (void) gets(&line[strlen(line)]); 56410294Ssam makeargv(); 56510294Ssam argc = margc; 56610294Ssam argv = margv; 56710294Ssam } 56810294Ssam if (argc < 2) { 56910294Ssam usage: 57026049Sminshall printf("usage: %s remote-file [ local-file ]\n", argv[0]); 57126049Sminshall code = -1; 57237224Skarels return (0); 57310294Ssam } 57410294Ssam if (argc < 3) { 57526497Sminshall (void) strcat(line, " "); 57610294Ssam printf("(local-file) "); 57726497Sminshall (void) gets(&line[strlen(line)]); 57810294Ssam makeargv(); 57910294Ssam argc = margc; 58010294Ssam argv = margv; 58110294Ssam } 58210294Ssam if (argc < 3) 58310294Ssam goto usage; 58437225Skarels oldargv1 = argv[1]; 58537225Skarels oldargv2 = argv[2]; 58626049Sminshall if (!globulize(&argv[2])) { 58726049Sminshall code = -1; 58837224Skarels return (0); 58926049Sminshall } 59026049Sminshall if (loc && mcase) { 59126049Sminshall char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN]; 59226049Sminshall 59326049Sminshall while (*tp && !islower(*tp)) { 59426049Sminshall tp++; 59526049Sminshall } 59626049Sminshall if (!*tp) { 59726049Sminshall tp = argv[2]; 59826049Sminshall tp2 = tmpbuf; 59926049Sminshall while ((*tp2 = *tp) != NULL) { 60026049Sminshall if (isupper(*tp2)) { 60126049Sminshall *tp2 = 'a' + *tp2 - 'A'; 60226049Sminshall } 60326049Sminshall tp++; 60426049Sminshall tp2++; 60526049Sminshall } 60626049Sminshall argv[2] = tmpbuf; 60726049Sminshall } 60826049Sminshall } 60936940Skarels if (loc && ntflag) 61026049Sminshall argv[2] = dotrans(argv[2]); 61136940Skarels if (loc && mapflag) 61226049Sminshall argv[2] = domap(argv[2]); 61337224Skarels if (restartit) { 61437224Skarels struct stat stbuf; 61537224Skarels int ret; 61637224Skarels 61737224Skarels ret = stat(argv[2], &stbuf); 61837224Skarels if (restartit == 1) { 61937224Skarels if (ret < 0) { 62037224Skarels perror(argv[2]); 62137224Skarels return (0); 62237224Skarels } 62337224Skarels restart_point = stbuf.st_size; 62437224Skarels } else { 62537224Skarels if (ret == 0) { 62637224Skarels int overbose; 62737224Skarels 62837224Skarels overbose = verbose; 62937224Skarels if (debug == 0) 63037224Skarels verbose = -1; 63137224Skarels if (command("MDTM %s", argv[1]) == COMPLETE) { 63237224Skarels int yy, mo, day, hour, min, sec; 63337224Skarels struct tm *tm; 63437224Skarels verbose = overbose; 63537224Skarels sscanf(reply_string, 63637224Skarels "%*s %04d%02d%02d%02d%02d%02d", 63737224Skarels &yy, &mo, &day, &hour, &min, &sec); 63837224Skarels tm = gmtime(&stbuf.st_mtime); 63937224Skarels tm->tm_mon++; 64037224Skarels if (tm->tm_year > yy%100) 64137224Skarels return (1); 64237224Skarels else if (tm->tm_year == yy%100) { 64337224Skarels if (tm->tm_mon > mo) 64437224Skarels return (1); 64537224Skarels } else if (tm->tm_mon == mo) { 64637224Skarels if (tm->tm_mday > day) 64737224Skarels return (1); 64837224Skarels } else if (tm->tm_mday == day) { 64937224Skarels if (tm->tm_hour > hour) 65037224Skarels return (1); 65137224Skarels } else if (tm->tm_hour == hour) { 65237224Skarels if (tm->tm_min > min) 65337224Skarels return (1); 65437224Skarels } else if (tm->tm_min == min) { 65537224Skarels if (tm->tm_sec > sec) 65637224Skarels return (1); 65737224Skarels } 65837224Skarels } else { 65937224Skarels fputs(reply_string, stdout); 66037224Skarels verbose = overbose; 66137224Skarels return (0); 66237224Skarels } 66337224Skarels } 66437224Skarels } 66537224Skarels } 66637224Skarels 66737225Skarels recvrequest("RETR", argv[2], argv[1], mode, 66837225Skarels argv[1] != oldargv1 || argv[2] != oldargv2); 66937224Skarels restart_point = 0; 67037224Skarels return (0); 67110294Ssam } 67210294Ssam 67326049Sminshall mabort() 67426049Sminshall { 67526049Sminshall int ointer; 67626049Sminshall extern jmp_buf jabort; 67726049Sminshall 67826049Sminshall printf("\n"); 67926049Sminshall (void) fflush(stdout); 68026049Sminshall if (mflag && fromatty) { 68126049Sminshall ointer = interactive; 68226049Sminshall interactive = 1; 68326049Sminshall if (confirm("Continue with", mname)) { 68426049Sminshall interactive = ointer; 68526049Sminshall longjmp(jabort,0); 68626049Sminshall } 68726049Sminshall interactive = ointer; 68826049Sminshall } 68926049Sminshall mflag = 0; 69026049Sminshall longjmp(jabort,0); 69126049Sminshall } 69226049Sminshall 69311353Ssam /* 69411353Ssam * Get multiple files. 69511353Ssam */ 69611353Ssam mget(argc, argv) 69711353Ssam char *argv[]; 69811353Ssam { 69926049Sminshall char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN]; 70026049Sminshall int ointer, (*oldintr)(), mabort(); 70126049Sminshall extern jmp_buf jabort; 70211353Ssam 70311353Ssam if (argc < 2) { 70426497Sminshall (void) strcat(line, " "); 70511756Ssam printf("(remote-files) "); 70626497Sminshall (void) gets(&line[strlen(line)]); 70711353Ssam makeargv(); 70811353Ssam argc = margc; 70911353Ssam argv = margv; 71011353Ssam } 71111353Ssam if (argc < 2) { 71226049Sminshall printf("usage:%s remote-files\n", argv[0]); 71326049Sminshall code = -1; 71411353Ssam return; 71511353Ssam } 71626049Sminshall mname = argv[0]; 71726049Sminshall mflag = 1; 71826049Sminshall oldintr = signal(SIGINT,mabort); 71926049Sminshall (void) setjmp(jabort); 72026497Sminshall while ((cp = remglob(argv,proxy)) != NULL) { 72126049Sminshall if (*cp == '\0') { 72226049Sminshall mflag = 0; 72326049Sminshall continue; 72426049Sminshall } 72526049Sminshall if (mflag && confirm(argv[0], cp)) { 72626049Sminshall tp = cp; 72726049Sminshall if (mcase) { 72826049Sminshall while (*tp && !islower(*tp)) { 72926049Sminshall tp++; 73026049Sminshall } 73126049Sminshall if (!*tp) { 73226049Sminshall tp = cp; 73326049Sminshall tp2 = tmpbuf; 73426049Sminshall while ((*tp2 = *tp) != NULL) { 73526049Sminshall if (isupper(*tp2)) { 73626049Sminshall *tp2 = 'a' + *tp2 - 'A'; 73726049Sminshall } 73826049Sminshall tp++; 73926049Sminshall tp2++; 74026049Sminshall } 74126049Sminshall } 74226049Sminshall tp = tmpbuf; 74326049Sminshall } 74426049Sminshall if (ntflag) { 74526049Sminshall tp = dotrans(tp); 74626049Sminshall } 74726049Sminshall if (mapflag) { 74826049Sminshall tp = domap(tp); 74926049Sminshall } 75037225Skarels recvrequest("RETR", tp, cp, "w", 75137225Skarels tp != cp || !interactive); 75226049Sminshall if (!mflag && fromatty) { 75326049Sminshall ointer = interactive; 75426049Sminshall interactive = 1; 75526049Sminshall if (confirm("Continue with","mget")) { 75626049Sminshall mflag++; 75726049Sminshall } 75826049Sminshall interactive = ointer; 75926049Sminshall } 76026049Sminshall } 76126049Sminshall } 76226049Sminshall (void) signal(SIGINT,oldintr); 76326049Sminshall mflag = 0; 76411650Ssam } 76511650Ssam 76611650Ssam char * 76726497Sminshall remglob(argv,doswitch) 76811650Ssam char *argv[]; 76926497Sminshall int doswitch; 77011650Ssam { 77111756Ssam char temp[16]; 77211650Ssam static char buf[MAXPATHLEN]; 77311650Ssam static FILE *ftemp = NULL; 77411650Ssam static char **args; 77513212Ssam int oldverbose, oldhash; 77611756Ssam char *cp, *mode; 77711650Ssam 77826049Sminshall if (!mflag) { 77926049Sminshall if (!doglob) { 78026049Sminshall args = NULL; 78126049Sminshall } 78226049Sminshall else { 78326049Sminshall if (ftemp) { 78426497Sminshall (void) fclose(ftemp); 78526049Sminshall ftemp = NULL; 78626049Sminshall } 78726049Sminshall } 78826049Sminshall return(NULL); 78926049Sminshall } 79011650Ssam if (!doglob) { 79111756Ssam if (args == NULL) 79211650Ssam args = argv; 79311650Ssam if ((cp = *++args) == NULL) 79411650Ssam args = NULL; 79511650Ssam return (cp); 79611353Ssam } 79711650Ssam if (ftemp == NULL) { 79837458Skarels (void) strcpy(temp, _PATH_TMP); 79926497Sminshall (void) mktemp(temp); 80011650Ssam oldverbose = verbose, verbose = 0; 80113212Ssam oldhash = hash, hash = 0; 80226049Sminshall if (doswitch) { 80326049Sminshall pswitch(!proxy); 80426049Sminshall } 80511756Ssam for (mode = "w"; *++argv != NULL; mode = "a") 80637225Skarels recvrequest ("NLST", temp, *argv, mode, 0); 80726049Sminshall if (doswitch) { 80826049Sminshall pswitch(!proxy); 80926049Sminshall } 81013212Ssam verbose = oldverbose; hash = oldhash; 81111650Ssam ftemp = fopen(temp, "r"); 81226497Sminshall (void) unlink(temp); 81311650Ssam if (ftemp == NULL) { 81411650Ssam printf("can't find list of remote files, oops\n"); 81511756Ssam return (NULL); 81611353Ssam } 81711353Ssam } 81811650Ssam if (fgets(buf, sizeof (buf), ftemp) == NULL) { 81926497Sminshall (void) fclose(ftemp), ftemp = NULL; 82011650Ssam return (NULL); 82111353Ssam } 82211650Ssam if ((cp = index(buf, '\n')) != NULL) 82311650Ssam *cp = '\0'; 82411650Ssam return (buf); 82511353Ssam } 82611353Ssam 82710294Ssam char * 82810294Ssam onoff(bool) 82910294Ssam int bool; 83010294Ssam { 83110294Ssam 83210294Ssam return (bool ? "on" : "off"); 83310294Ssam } 83410294Ssam 83510294Ssam /* 83610294Ssam * Show status. 83710294Ssam */ 83826497Sminshall /*ARGSUSED*/ 83910294Ssam status(argc, argv) 84010294Ssam char *argv[]; 84110294Ssam { 84226049Sminshall int i; 84310294Ssam 84410294Ssam if (connected) 84510294Ssam printf("Connected to %s.\n", hostname); 84610294Ssam else 84710294Ssam printf("Not connected.\n"); 84826049Sminshall if (!proxy) { 84926049Sminshall pswitch(1); 85026049Sminshall if (connected) { 85126049Sminshall printf("Connected for proxy commands to %s.\n", hostname); 85226049Sminshall } 85326049Sminshall else { 85426049Sminshall printf("No proxy connection.\n"); 85526049Sminshall } 85626049Sminshall pswitch(0); 85726049Sminshall } 85810294Ssam printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n", 85910294Ssam modename, typename, formname, structname); 86011353Ssam printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 86111353Ssam onoff(verbose), onoff(bell), onoff(interactive), 86211353Ssam onoff(doglob)); 86326049Sminshall printf("Store unique: %s; Receive unique: %s\n", onoff(sunique), 86426049Sminshall onoff(runique)); 86526049Sminshall printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag)); 86626049Sminshall if (ntflag) { 86726049Sminshall printf("Ntrans: (in) %s (out) %s\n", ntin,ntout); 86826049Sminshall } 86926049Sminshall else { 87026049Sminshall printf("Ntrans: off\n"); 87126049Sminshall } 87226049Sminshall if (mapflag) { 87326049Sminshall printf("Nmap: (in) %s (out) %s\n", mapin, mapout); 87426049Sminshall } 87526049Sminshall else { 87626049Sminshall printf("Nmap: off\n"); 87726049Sminshall } 87814143Ssam printf("Hash mark printing: %s; Use of PORT cmds: %s\n", 87914143Ssam onoff(hash), onoff(sendport)); 88026049Sminshall if (macnum > 0) { 88126049Sminshall printf("Macros:\n"); 88226049Sminshall for (i=0; i<macnum; i++) { 88326049Sminshall printf("\t%s\n",macros[i].mac_name); 88426049Sminshall } 88526049Sminshall } 88626049Sminshall code = 0; 88710294Ssam } 88810294Ssam 88910294Ssam /* 89010294Ssam * Set beep on cmd completed mode. 89110294Ssam */ 89210294Ssam /*VARARGS*/ 89310294Ssam setbell() 89410294Ssam { 89510294Ssam 89610294Ssam bell = !bell; 89710294Ssam printf("Bell mode %s.\n", onoff(bell)); 89826049Sminshall code = bell; 89910294Ssam } 90010294Ssam 90110294Ssam /* 90210294Ssam * Turn on packet tracing. 90310294Ssam */ 90410294Ssam /*VARARGS*/ 90510294Ssam settrace() 90610294Ssam { 90710294Ssam 90810294Ssam trace = !trace; 90910294Ssam printf("Packet tracing %s.\n", onoff(trace)); 91026049Sminshall code = trace; 91110294Ssam } 91210294Ssam 91310294Ssam /* 91411650Ssam * Toggle hash mark printing during transfers. 91511650Ssam */ 91611650Ssam /*VARARGS*/ 91711650Ssam sethash() 91811650Ssam { 91911650Ssam 92011650Ssam hash = !hash; 92111650Ssam printf("Hash mark printing %s", onoff(hash)); 92226049Sminshall code = hash; 92311650Ssam if (hash) 92437224Skarels printf(" (%d bytes/hash mark)", 1024); 92511650Ssam printf(".\n"); 92611650Ssam } 92711650Ssam 92811650Ssam /* 92910294Ssam * Turn on printing of server echo's. 93010294Ssam */ 93110294Ssam /*VARARGS*/ 93210294Ssam setverbose() 93310294Ssam { 93410294Ssam 93510294Ssam verbose = !verbose; 93610294Ssam printf("Verbose mode %s.\n", onoff(verbose)); 93726049Sminshall code = verbose; 93810294Ssam } 93910294Ssam 94010294Ssam /* 94111650Ssam * Toggle PORT cmd use before each data connection. 94211650Ssam */ 94311650Ssam /*VARARGS*/ 94411650Ssam setport() 94511650Ssam { 94611650Ssam 94711650Ssam sendport = !sendport; 94811650Ssam printf("Use of PORT cmds %s.\n", onoff(sendport)); 94926049Sminshall code = sendport; 95011650Ssam } 95111650Ssam 95211650Ssam /* 95310294Ssam * Turn on interactive prompting 95410294Ssam * during mget, mput, and mdelete. 95510294Ssam */ 95610294Ssam /*VARARGS*/ 95710294Ssam setprompt() 95810294Ssam { 95910294Ssam 96010294Ssam interactive = !interactive; 96110294Ssam printf("Interactive mode %s.\n", onoff(interactive)); 96226049Sminshall code = interactive; 96310294Ssam } 96410294Ssam 96510294Ssam /* 96611353Ssam * Toggle metacharacter interpretation 96711353Ssam * on local file names. 96811353Ssam */ 96911353Ssam /*VARARGS*/ 97011353Ssam setglob() 97111353Ssam { 97211353Ssam 97311353Ssam doglob = !doglob; 97411353Ssam printf("Globbing %s.\n", onoff(doglob)); 97526049Sminshall code = doglob; 97611353Ssam } 97711353Ssam 97811353Ssam /* 97910294Ssam * Set debugging mode on/off and/or 98010294Ssam * set level of debugging. 98110294Ssam */ 98211756Ssam /*VARARGS*/ 98310294Ssam setdebug(argc, argv) 98410294Ssam char *argv[]; 98510294Ssam { 98610294Ssam int val; 98710294Ssam 98810294Ssam if (argc > 1) { 98910294Ssam val = atoi(argv[1]); 99010294Ssam if (val < 0) { 99110294Ssam printf("%s: bad debugging value.\n", argv[1]); 99226049Sminshall code = -1; 99310294Ssam return; 99410294Ssam } 99510294Ssam } else 99610294Ssam val = !debug; 99710294Ssam debug = val; 99810294Ssam if (debug) 99910294Ssam options |= SO_DEBUG; 100010294Ssam else 100110294Ssam options &= ~SO_DEBUG; 100210294Ssam printf("Debugging %s (debug=%d).\n", onoff(debug), debug); 100326049Sminshall code = debug > 0; 100410294Ssam } 100510294Ssam 100610294Ssam /* 100710294Ssam * Set current working directory 100810294Ssam * on remote machine. 100910294Ssam */ 101010294Ssam cd(argc, argv) 101110294Ssam char *argv[]; 101210294Ssam { 101310294Ssam 101410294Ssam if (argc < 2) { 101526497Sminshall (void) strcat(line, " "); 101610294Ssam printf("(remote-directory) "); 101726497Sminshall (void) gets(&line[strlen(line)]); 101810294Ssam makeargv(); 101910294Ssam argc = margc; 102010294Ssam argv = margv; 102110294Ssam } 102210294Ssam if (argc < 2) { 102326049Sminshall printf("usage:%s remote-directory\n", argv[0]); 102426049Sminshall code = -1; 102510294Ssam return; 102610294Ssam } 102737224Skarels if (command("CWD %s", argv[1]) == ERROR && code == 500) { 102837224Skarels if (verbose) 102937224Skarels printf("CWD command not recognized, trying XCWD\n"); 103037224Skarels (void) command("XCWD %s", argv[1]); 103137224Skarels } 103210294Ssam } 103310294Ssam 103410294Ssam /* 103510294Ssam * Set current working directory 103610294Ssam * on local machine. 103710294Ssam */ 103810294Ssam lcd(argc, argv) 103910294Ssam char *argv[]; 104010294Ssam { 104111353Ssam char buf[MAXPATHLEN]; 104210294Ssam 104311353Ssam if (argc < 2) 104411353Ssam argc++, argv[1] = home; 104510294Ssam if (argc != 2) { 104626049Sminshall printf("usage:%s local-directory\n", argv[0]); 104726049Sminshall code = -1; 104810294Ssam return; 104910294Ssam } 105026049Sminshall if (!globulize(&argv[1])) { 105126049Sminshall code = -1; 105211353Ssam return; 105326049Sminshall } 105411353Ssam if (chdir(argv[1]) < 0) { 105510294Ssam perror(argv[1]); 105626049Sminshall code = -1; 105711353Ssam return; 105811353Ssam } 105911353Ssam printf("Local directory now %s\n", getwd(buf)); 106026049Sminshall code = 0; 106110294Ssam } 106210294Ssam 106310294Ssam /* 106410294Ssam * Delete a single file. 106510294Ssam */ 106610294Ssam delete(argc, argv) 106710294Ssam char *argv[]; 106810294Ssam { 106910294Ssam 107010294Ssam if (argc < 2) { 107126497Sminshall (void) strcat(line, " "); 107210294Ssam printf("(remote-file) "); 107326497Sminshall (void) gets(&line[strlen(line)]); 107410294Ssam makeargv(); 107510294Ssam argc = margc; 107610294Ssam argv = margv; 107710294Ssam } 107810294Ssam if (argc < 2) { 107926049Sminshall printf("usage:%s remote-file\n", argv[0]); 108026049Sminshall code = -1; 108110294Ssam return; 108210294Ssam } 108310294Ssam (void) command("DELE %s", argv[1]); 108410294Ssam } 108510294Ssam 108610294Ssam /* 108711650Ssam * Delete multiple files. 108811650Ssam */ 108911650Ssam mdelete(argc, argv) 109011650Ssam char *argv[]; 109111650Ssam { 109211650Ssam char *cp; 109326049Sminshall int ointer, (*oldintr)(), mabort(); 109426049Sminshall extern jmp_buf jabort; 109511650Ssam 109611650Ssam if (argc < 2) { 109726497Sminshall (void) strcat(line, " "); 109811650Ssam printf("(remote-files) "); 109926497Sminshall (void) gets(&line[strlen(line)]); 110011650Ssam makeargv(); 110111650Ssam argc = margc; 110211650Ssam argv = margv; 110311650Ssam } 110411650Ssam if (argc < 2) { 110526049Sminshall printf("usage:%s remote-files\n", argv[0]); 110626049Sminshall code = -1; 110711650Ssam return; 110811650Ssam } 110926049Sminshall mname = argv[0]; 111026049Sminshall mflag = 1; 111126049Sminshall oldintr = signal(SIGINT, mabort); 111226049Sminshall (void) setjmp(jabort); 111326497Sminshall while ((cp = remglob(argv,0)) != NULL) { 111426049Sminshall if (*cp == '\0') { 111526049Sminshall mflag = 0; 111626049Sminshall continue; 111726049Sminshall } 111826049Sminshall if (mflag && confirm(argv[0], cp)) { 111911650Ssam (void) command("DELE %s", cp); 112026049Sminshall if (!mflag && fromatty) { 112126049Sminshall ointer = interactive; 112226049Sminshall interactive = 1; 112326049Sminshall if (confirm("Continue with", "mdelete")) { 112426049Sminshall mflag++; 112526049Sminshall } 112626049Sminshall interactive = ointer; 112726049Sminshall } 112826049Sminshall } 112926049Sminshall } 113026049Sminshall (void) signal(SIGINT, oldintr); 113126049Sminshall mflag = 0; 113211650Ssam } 113311756Ssam 113411650Ssam /* 113510294Ssam * Rename a remote file. 113610294Ssam */ 113710294Ssam renamefile(argc, argv) 113810294Ssam char *argv[]; 113910294Ssam { 114010294Ssam 114110294Ssam if (argc < 2) { 114226497Sminshall (void) strcat(line, " "); 114310294Ssam printf("(from-name) "); 114426497Sminshall (void) gets(&line[strlen(line)]); 114510294Ssam makeargv(); 114610294Ssam argc = margc; 114710294Ssam argv = margv; 114810294Ssam } 114910294Ssam if (argc < 2) { 115010294Ssam usage: 115110294Ssam printf("%s from-name to-name\n", argv[0]); 115226049Sminshall code = -1; 115310294Ssam return; 115410294Ssam } 115510294Ssam if (argc < 3) { 115626497Sminshall (void) strcat(line, " "); 115710294Ssam printf("(to-name) "); 115826497Sminshall (void) gets(&line[strlen(line)]); 115910294Ssam makeargv(); 116010294Ssam argc = margc; 116110294Ssam argv = margv; 116210294Ssam } 116310294Ssam if (argc < 3) 116410294Ssam goto usage; 116510294Ssam if (command("RNFR %s", argv[1]) == CONTINUE) 116610294Ssam (void) command("RNTO %s", argv[2]); 116710294Ssam } 116810294Ssam 116910294Ssam /* 117010294Ssam * Get a directory listing 117110294Ssam * of remote files. 117210294Ssam */ 117310294Ssam ls(argc, argv) 117410294Ssam char *argv[]; 117510294Ssam { 117611756Ssam char *cmd; 117710294Ssam 117810294Ssam if (argc < 2) 117910294Ssam argc++, argv[1] = NULL; 118010294Ssam if (argc < 3) 118110294Ssam argc++, argv[2] = "-"; 118211756Ssam if (argc > 3) { 118311756Ssam printf("usage: %s remote-directory local-file\n", argv[0]); 118426049Sminshall code = -1; 118511756Ssam return; 118611756Ssam } 118736935Skarels cmd = argv[0][0] == 'n' ? "NLST" : "LIST"; 118826049Sminshall if (strcmp(argv[2], "-") && !globulize(&argv[2])) { 118926049Sminshall code = -1; 119011353Ssam return; 119126049Sminshall } 119232344Scsvsj if (strcmp(argv[2], "-") && *argv[2] != '|') 119332344Scsvsj if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) { 119432344Scsvsj code = -1; 119532344Scsvsj return; 119632344Scsvsj } 119737225Skarels recvrequest(cmd, argv[2], argv[1], "w", 0); 119810294Ssam } 119910294Ssam 120010294Ssam /* 120111756Ssam * Get a directory listing 120211756Ssam * of multiple remote files. 120311756Ssam */ 120411756Ssam mls(argc, argv) 120511756Ssam char *argv[]; 120611756Ssam { 120726049Sminshall char *cmd, mode[1], *dest; 120826049Sminshall int ointer, i, (*oldintr)(), mabort(); 120926049Sminshall extern jmp_buf jabort; 121011756Ssam 121113212Ssam if (argc < 2) { 121226497Sminshall (void) strcat(line, " "); 121313212Ssam printf("(remote-files) "); 121426497Sminshall (void) gets(&line[strlen(line)]); 121513212Ssam makeargv(); 121613212Ssam argc = margc; 121713212Ssam argv = margv; 121813212Ssam } 121913212Ssam if (argc < 3) { 122026497Sminshall (void) strcat(line, " "); 122113212Ssam printf("(local-file) "); 122226497Sminshall (void) gets(&line[strlen(line)]); 122313212Ssam makeargv(); 122413212Ssam argc = margc; 122513212Ssam argv = margv; 122613212Ssam } 122713212Ssam if (argc < 3) { 122826049Sminshall printf("usage:%s remote-files local-file\n", argv[0]); 122926049Sminshall code = -1; 123013212Ssam return; 123113212Ssam } 123213212Ssam dest = argv[argc - 1]; 123313212Ssam argv[argc - 1] = NULL; 123426049Sminshall if (strcmp(dest, "-") && *dest != '|') 123526049Sminshall if (!globulize(&dest) || !confirm("output to local-file:", dest)) { 123626049Sminshall code = -1; 123713212Ssam return; 123826049Sminshall } 123936940Skarels cmd = argv[0][1] == 'l' ? "NLST" : "LIST"; 124026049Sminshall mname = argv[0]; 124126049Sminshall mflag = 1; 124226049Sminshall oldintr = signal(SIGINT, mabort); 124326049Sminshall (void) setjmp(jabort); 124426049Sminshall for (i = 1; mflag && i < argc-1; ++i) { 124526049Sminshall *mode = (i == 1) ? 'w' : 'a'; 124637225Skarels recvrequest(cmd, dest, argv[i], mode, 0); 124726049Sminshall if (!mflag && fromatty) { 124826049Sminshall ointer = interactive; 124926049Sminshall interactive = 1; 125026049Sminshall if (confirm("Continue with", argv[0])) { 125126049Sminshall mflag ++; 125226049Sminshall } 125326049Sminshall interactive = ointer; 125426049Sminshall } 125526049Sminshall } 125626049Sminshall (void) signal(SIGINT, oldintr); 125726049Sminshall mflag = 0; 125811756Ssam } 125911756Ssam 126011756Ssam /* 126110294Ssam * Do a shell escape 126210294Ssam */ 126326497Sminshall /*ARGSUSED*/ 126410294Ssam shell(argc, argv) 126510294Ssam char *argv[]; 126610294Ssam { 126726497Sminshall int pid, (*old1)(), (*old2)(); 126826049Sminshall char shellnam[40], *shell, *namep; 126926497Sminshall union wait status; 127010294Ssam 127111756Ssam old1 = signal (SIGINT, SIG_IGN); 127211756Ssam old2 = signal (SIGQUIT, SIG_IGN); 127311756Ssam if ((pid = fork()) == 0) { 127411756Ssam for (pid = 3; pid < 20; pid++) 127526497Sminshall (void) close(pid); 127626497Sminshall (void) signal(SIGINT, SIG_DFL); 127726497Sminshall (void) signal(SIGQUIT, SIG_DFL); 127825908Smckusick shell = getenv("SHELL"); 127925908Smckusick if (shell == NULL) 128037458Skarels shell = _PATH_BSHELL; 128125908Smckusick namep = rindex(shell,'/'); 128225908Smckusick if (namep == NULL) 128325908Smckusick namep = shell; 128426497Sminshall (void) strcpy(shellnam,"-"); 128526497Sminshall (void) strcat(shellnam, ++namep); 128626049Sminshall if (strcmp(namep, "sh") != 0) 128726049Sminshall shellnam[0] = '+'; 128826049Sminshall if (debug) { 128926049Sminshall printf ("%s\n", shell); 129026497Sminshall (void) fflush (stdout); 129111756Ssam } 129226049Sminshall if (argc > 1) { 129326049Sminshall execl(shell,shellnam,"-c",altarg,(char *)0); 129426049Sminshall } 129526049Sminshall else { 129626049Sminshall execl(shell,shellnam,(char *)0); 129726049Sminshall } 129825908Smckusick perror(shell); 129926049Sminshall code = -1; 130011756Ssam exit(1); 130126049Sminshall } 130211756Ssam if (pid > 0) 130311756Ssam while (wait(&status) != pid) 130411756Ssam ; 130526497Sminshall (void) signal(SIGINT, old1); 130626497Sminshall (void) signal(SIGQUIT, old2); 130726049Sminshall if (pid == -1) { 130811756Ssam perror("Try again later"); 130926049Sminshall code = -1; 131026049Sminshall } 131126049Sminshall else { 131226049Sminshall code = 0; 131326049Sminshall } 131411756Ssam return (0); 131510294Ssam } 131610294Ssam 131710294Ssam /* 131810294Ssam * Send new user information (re-login) 131910294Ssam */ 132010294Ssam user(argc, argv) 132110294Ssam int argc; 132210294Ssam char **argv; 132310294Ssam { 132435658Sbostic char acct[80], *getpass(); 132526049Sminshall int n, aflag = 0; 132610294Ssam 132710294Ssam if (argc < 2) { 132826497Sminshall (void) strcat(line, " "); 132910294Ssam printf("(username) "); 133026497Sminshall (void) gets(&line[strlen(line)]); 133110294Ssam makeargv(); 133210294Ssam argc = margc; 133310294Ssam argv = margv; 133410294Ssam } 133510294Ssam if (argc > 4) { 133610294Ssam printf("usage: %s username [password] [account]\n", argv[0]); 133726049Sminshall code = -1; 133811756Ssam return (0); 133910294Ssam } 134010294Ssam n = command("USER %s", argv[1]); 134110294Ssam if (n == CONTINUE) { 134210294Ssam if (argc < 3 ) 134335658Sbostic argv[2] = getpass("Password: "), argc++; 134410294Ssam n = command("PASS %s", argv[2]); 134510294Ssam } 134610294Ssam if (n == CONTINUE) { 134710294Ssam if (argc < 4) { 134810294Ssam printf("Account: "); (void) fflush(stdout); 134910294Ssam (void) fgets(acct, sizeof(acct) - 1, stdin); 135010294Ssam acct[strlen(acct) - 1] = '\0'; 135110294Ssam argv[3] = acct; argc++; 135210294Ssam } 135326049Sminshall n = command("ACCT %s", argv[3]); 135426049Sminshall aflag++; 135510294Ssam } 135610294Ssam if (n != COMPLETE) { 135726497Sminshall fprintf(stdout, "Login failed.\n"); 135810294Ssam return (0); 135910294Ssam } 136026049Sminshall if (!aflag && argc == 4) { 136126049Sminshall (void) command("ACCT %s", argv[3]); 136226049Sminshall } 136310294Ssam return (1); 136410294Ssam } 136510294Ssam 136610294Ssam /* 136710294Ssam * Print working directory. 136810294Ssam */ 136910294Ssam /*VARARGS*/ 137010294Ssam pwd() 137110294Ssam { 137237224Skarels int oldverbose = verbose; 137311756Ssam 137437224Skarels /* 137537224Skarels * If we aren't verbose, this doesn't do anything! 137637224Skarels */ 137737224Skarels verbose = 1; 137837224Skarels if (command("PWD") == ERROR && code == 500) { 137937224Skarels printf("PWD command not recognized, trying XPWD\n"); 138037224Skarels (void) command("XPWD"); 138137224Skarels } 138237224Skarels verbose = oldverbose; 138310294Ssam } 138410294Ssam 138510294Ssam /* 138610294Ssam * Make a directory. 138710294Ssam */ 138810294Ssam makedir(argc, argv) 138910294Ssam char *argv[]; 139010294Ssam { 139110294Ssam 139210294Ssam if (argc < 2) { 139326497Sminshall (void) strcat(line, " "); 139410294Ssam printf("(directory-name) "); 139526497Sminshall (void) gets(&line[strlen(line)]); 139610294Ssam makeargv(); 139710294Ssam argc = margc; 139810294Ssam argv = margv; 139910294Ssam } 140010294Ssam if (argc < 2) { 140126049Sminshall printf("usage: %s directory-name\n", argv[0]); 140226049Sminshall code = -1; 140310294Ssam return; 140410294Ssam } 140537224Skarels if (command("MKD %s", argv[1]) == ERROR && code == 500) { 140637224Skarels if (verbose) 140737224Skarels printf("MKD command not recognized, trying XMKD\n"); 140837224Skarels (void) command("XMKD %s", argv[1]); 140937224Skarels } 141010294Ssam } 141110294Ssam 141210294Ssam /* 141310294Ssam * Remove a directory. 141410294Ssam */ 141510294Ssam removedir(argc, argv) 141610294Ssam char *argv[]; 141710294Ssam { 141810294Ssam 141910294Ssam if (argc < 2) { 142026497Sminshall (void) strcat(line, " "); 142110294Ssam printf("(directory-name) "); 142226497Sminshall (void) gets(&line[strlen(line)]); 142310294Ssam makeargv(); 142410294Ssam argc = margc; 142510294Ssam argv = margv; 142610294Ssam } 142710294Ssam if (argc < 2) { 142826049Sminshall printf("usage: %s directory-name\n", argv[0]); 142926049Sminshall code = -1; 143010294Ssam return; 143110294Ssam } 143237224Skarels if (command("RMD %s", argv[1]) == ERROR && code == 500) { 143337224Skarels if (verbose) 143437224Skarels printf("RMD command not recognized, trying XRMD\n"); 143537224Skarels (void) command("XRMD %s", argv[1]); 143637224Skarels } 143710294Ssam } 143810294Ssam 143910294Ssam /* 144010294Ssam * Send a line, verbatim, to the remote machine. 144110294Ssam */ 144210294Ssam quote(argc, argv) 144310294Ssam char *argv[]; 144410294Ssam { 144510294Ssam int i; 144610294Ssam char buf[BUFSIZ]; 144710294Ssam 144810294Ssam if (argc < 2) { 144926497Sminshall (void) strcat(line, " "); 145010294Ssam printf("(command line to send) "); 145126497Sminshall (void) gets(&line[strlen(line)]); 145210294Ssam makeargv(); 145310294Ssam argc = margc; 145410294Ssam argv = margv; 145510294Ssam } 145610294Ssam if (argc < 2) { 145710294Ssam printf("usage: %s line-to-send\n", argv[0]); 145826049Sminshall code = -1; 145910294Ssam return; 146010294Ssam } 146126497Sminshall (void) strcpy(buf, argv[1]); 146210294Ssam for (i = 2; i < argc; i++) { 146326497Sminshall (void) strcat(buf, " "); 146426497Sminshall (void) strcat(buf, argv[i]); 146510294Ssam } 146626049Sminshall if (command(buf) == PRELIM) { 146726049Sminshall while (getreply(0) == PRELIM); 146826049Sminshall } 146910294Ssam } 147010294Ssam 147110294Ssam /* 147237224Skarels * Send a SITE command to the remote machine. The line 147337224Skarels * is sent almost verbatim to the remote machine, the 147437224Skarels * first argument is changed to SITE. 147537224Skarels */ 147637224Skarels 147737224Skarels site(argc, argv) 147837224Skarels char *argv[]; 147937224Skarels { 148037224Skarels int i; 148137224Skarels char buf[BUFSIZ]; 148237224Skarels 148337224Skarels if (argc < 2) { 148437224Skarels (void) strcat(line, " "); 148537224Skarels printf("(arguments to SITE command) "); 148637224Skarels (void) gets(&line[strlen(line)]); 148737224Skarels makeargv(); 148837224Skarels argc = margc; 148937224Skarels argv = margv; 149037224Skarels } 149137224Skarels if (argc < 2) { 149237224Skarels printf("usage: %s line-to-send\n", argv[0]); 149337224Skarels code = -1; 149437224Skarels return; 149537224Skarels } 149637224Skarels (void) strcpy(buf, "SITE "); 149737224Skarels (void) strcat(buf, argv[1]); 149837224Skarels for (i = 2; i < argc; i++) { 149937224Skarels (void) strcat(buf, " "); 150037224Skarels (void) strcat(buf, argv[i]); 150137224Skarels } 150237224Skarels if (command(buf) == PRELIM) { 150337224Skarels while (getreply(0) == PRELIM); 150437224Skarels } 150537224Skarels } 150637224Skarels 150737224Skarels do_chmod(argc, argv) 150837224Skarels char *argv[]; 150937224Skarels { 151037224Skarels if (argc == 2) { 151137224Skarels printf("usage: %s mode file-name\n", argv[0]); 151237224Skarels code = -1; 151337224Skarels return; 151437224Skarels } 151537224Skarels if (argc < 3) { 151637224Skarels (void) strcat(line, " "); 151737224Skarels printf("(mode and file-name) "); 151837224Skarels (void) gets(&line[strlen(line)]); 151937224Skarels makeargv(); 152037224Skarels argc = margc; 152137224Skarels argv = margv; 152237224Skarels } 152337224Skarels if (argc != 3) { 152437224Skarels printf("usage: %s mode file-name\n", argv[0]); 152537224Skarels code = -1; 152637224Skarels return; 152737224Skarels } 152837224Skarels (void)command("SITE CHMOD %s %s", argv[1], argv[2]); 152937224Skarels } 153037224Skarels 153137224Skarels do_umask(argc, argv) 153237224Skarels char *argv[]; 153337224Skarels { 153437224Skarels int oldverbose = verbose; 153537224Skarels 153637224Skarels verbose = 1; 153737224Skarels (void) command(argc == 1 ? "SITE UMASK" : "SITE UMASK %s", argv[1]); 153837224Skarels verbose = oldverbose; 153937224Skarels } 154037224Skarels 154137224Skarels idle(argc, argv) 154237224Skarels char *argv[]; 154337224Skarels { 154437224Skarels int oldverbose = verbose; 154537224Skarels 154637224Skarels verbose = 1; 154737224Skarels (void) command(argc == 1 ? "SITE IDLE" : "SITE IDLE %s", argv[1]); 154837224Skarels verbose = oldverbose; 154937224Skarels } 155037224Skarels 155137224Skarels /* 155210294Ssam * Ask the other side for help. 155310294Ssam */ 155410294Ssam rmthelp(argc, argv) 155510294Ssam char *argv[]; 155610294Ssam { 155710294Ssam int oldverbose = verbose; 155810294Ssam 155910294Ssam verbose = 1; 156010294Ssam (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]); 156110294Ssam verbose = oldverbose; 156210294Ssam } 156310294Ssam 156410294Ssam /* 156510294Ssam * Terminate session and exit. 156610294Ssam */ 156710294Ssam /*VARARGS*/ 156810294Ssam quit() 156910294Ssam { 157010294Ssam 157118286Sralph if (connected) 157218286Sralph disconnect(); 157326049Sminshall pswitch(1); 157426049Sminshall if (connected) { 157526049Sminshall disconnect(); 157626049Sminshall } 157710294Ssam exit(0); 157810294Ssam } 157910294Ssam 158010294Ssam /* 158110294Ssam * Terminate session, but don't exit. 158210294Ssam */ 158310294Ssam disconnect() 158410294Ssam { 158510294Ssam extern FILE *cout; 158610294Ssam extern int data; 158710294Ssam 158810294Ssam if (!connected) 158910294Ssam return; 159010294Ssam (void) command("QUIT"); 159126049Sminshall if (cout) { 159226049Sminshall (void) fclose(cout); 159326049Sminshall } 159410294Ssam cout = NULL; 159510294Ssam connected = 0; 159610294Ssam data = -1; 159726049Sminshall if (!proxy) { 159826049Sminshall macnum = 0; 159926049Sminshall } 160010294Ssam } 160111353Ssam 160211650Ssam confirm(cmd, file) 160311353Ssam char *cmd, *file; 160411353Ssam { 160511353Ssam char line[BUFSIZ]; 160611353Ssam 160711353Ssam if (!interactive) 160811650Ssam return (1); 160911353Ssam printf("%s %s? ", cmd, file); 161026497Sminshall (void) fflush(stdout); 161126497Sminshall (void) gets(line); 161211650Ssam return (*line != 'n' && *line != 'N'); 161311353Ssam } 161411353Ssam 161511353Ssam fatal(msg) 161611353Ssam char *msg; 161711353Ssam { 161811353Ssam 161926497Sminshall fprintf(stderr, "ftp: %s\n", msg); 162011353Ssam exit(1); 162111353Ssam } 162211353Ssam 162311353Ssam /* 162411353Ssam * Glob a local file name specification with 162511353Ssam * the expectation of a single return value. 162611353Ssam * Can't control multiple values being expanded 162711353Ssam * from the expression, we return only the first. 162811353Ssam */ 162911353Ssam globulize(cpp) 163011353Ssam char **cpp; 163111353Ssam { 163211353Ssam char **globbed; 163311353Ssam 163411353Ssam if (!doglob) 163511353Ssam return (1); 163611353Ssam globbed = glob(*cpp); 163711353Ssam if (globerr != NULL) { 163811353Ssam printf("%s: %s\n", *cpp, globerr); 163936421Sbostic if (globbed) { 164011353Ssam blkfree(globbed); 164136421Sbostic free(globbed); 164236421Sbostic } 164311353Ssam return (0); 164411353Ssam } 164511353Ssam if (globbed) { 164611353Ssam *cpp = *globbed++; 164711353Ssam /* don't waste too much memory */ 164836421Sbostic if (*globbed) { 164911353Ssam blkfree(globbed); 165036421Sbostic free(globbed); 165136421Sbostic } 165211353Ssam } 165311353Ssam return (1); 165411353Ssam } 165526049Sminshall 165626049Sminshall account(argc,argv) 165726049Sminshall int argc; 165826049Sminshall char **argv; 165926049Sminshall { 166035658Sbostic char acct[50], *getpass(), *ap; 166126049Sminshall 166226049Sminshall if (argc > 1) { 166326049Sminshall ++argv; 166426049Sminshall --argc; 166526049Sminshall (void) strncpy(acct,*argv,49); 166636268Sbostic acct[49] = '\0'; 166726049Sminshall while (argc > 1) { 166826049Sminshall --argc; 166926049Sminshall ++argv; 167026049Sminshall (void) strncat(acct,*argv, 49-strlen(acct)); 167126049Sminshall } 167226049Sminshall ap = acct; 167326049Sminshall } 167426049Sminshall else { 167535658Sbostic ap = getpass("Account:"); 167626049Sminshall } 167726049Sminshall (void) command("ACCT %s", ap); 167826049Sminshall } 167926049Sminshall 168026049Sminshall jmp_buf abortprox; 168126049Sminshall 168226049Sminshall proxabort() 168326049Sminshall { 168426049Sminshall extern int proxy; 168526049Sminshall 168626049Sminshall if (!proxy) { 168726049Sminshall pswitch(1); 168826049Sminshall } 168926049Sminshall if (connected) { 169026049Sminshall proxflag = 1; 169126049Sminshall } 169226049Sminshall else { 169326049Sminshall proxflag = 0; 169426049Sminshall } 169526049Sminshall pswitch(0); 169626049Sminshall longjmp(abortprox,1); 169726049Sminshall } 169826049Sminshall 169926049Sminshall doproxy(argc,argv) 170026049Sminshall int argc; 170126049Sminshall char *argv[]; 170226049Sminshall { 170326049Sminshall int (*oldintr)(), proxabort(); 170426049Sminshall register struct cmd *c; 170526049Sminshall struct cmd *getcmd(); 170626049Sminshall extern struct cmd cmdtab[]; 170726049Sminshall extern jmp_buf abortprox; 170826049Sminshall 170926049Sminshall if (argc < 2) { 171026497Sminshall (void) strcat(line, " "); 171126049Sminshall printf("(command) "); 171226497Sminshall (void) gets(&line[strlen(line)]); 171326049Sminshall makeargv(); 171426049Sminshall argc = margc; 171526049Sminshall argv = margv; 171626049Sminshall } 171726049Sminshall if (argc < 2) { 171826049Sminshall printf("usage:%s command\n", argv[0]); 171926049Sminshall code = -1; 172026049Sminshall return; 172126049Sminshall } 172226049Sminshall c = getcmd(argv[1]); 172326049Sminshall if (c == (struct cmd *) -1) { 172426049Sminshall printf("?Ambiguous command\n"); 172526497Sminshall (void) fflush(stdout); 172626049Sminshall code = -1; 172726049Sminshall return; 172826049Sminshall } 172926049Sminshall if (c == 0) { 173026049Sminshall printf("?Invalid command\n"); 173126497Sminshall (void) fflush(stdout); 173226049Sminshall code = -1; 173326049Sminshall return; 173426049Sminshall } 173526049Sminshall if (!c->c_proxy) { 173626049Sminshall printf("?Invalid proxy command\n"); 173726497Sminshall (void) fflush(stdout); 173826049Sminshall code = -1; 173926049Sminshall return; 174026049Sminshall } 174126049Sminshall if (setjmp(abortprox)) { 174226049Sminshall code = -1; 174326049Sminshall return; 174426049Sminshall } 174526049Sminshall oldintr = signal(SIGINT, proxabort); 174626049Sminshall pswitch(1); 174726049Sminshall if (c->c_conn && !connected) { 174826049Sminshall printf("Not connected\n"); 174926497Sminshall (void) fflush(stdout); 175026049Sminshall pswitch(0); 175126049Sminshall (void) signal(SIGINT, oldintr); 175226049Sminshall code = -1; 175326049Sminshall return; 175426049Sminshall } 175526049Sminshall (*c->c_handler)(argc-1, argv+1); 175626049Sminshall if (connected) { 175726049Sminshall proxflag = 1; 175826049Sminshall } 175926049Sminshall else { 176026049Sminshall proxflag = 0; 176126049Sminshall } 176226049Sminshall pswitch(0); 176326049Sminshall (void) signal(SIGINT, oldintr); 176426049Sminshall } 176526049Sminshall 176626049Sminshall setcase() 176726049Sminshall { 176826049Sminshall mcase = !mcase; 176926049Sminshall printf("Case mapping %s.\n", onoff(mcase)); 177026049Sminshall code = mcase; 177126049Sminshall } 177226049Sminshall 177326049Sminshall setcr() 177426049Sminshall { 177526049Sminshall crflag = !crflag; 177626049Sminshall printf("Carriage Return stripping %s.\n", onoff(crflag)); 177726049Sminshall code = crflag; 177826049Sminshall } 177926049Sminshall 178026049Sminshall setntrans(argc,argv) 178126049Sminshall int argc; 178226049Sminshall char *argv[]; 178326049Sminshall { 178426049Sminshall if (argc == 1) { 178526049Sminshall ntflag = 0; 178626049Sminshall printf("Ntrans off.\n"); 178726049Sminshall code = ntflag; 178826049Sminshall return; 178926049Sminshall } 179026049Sminshall ntflag++; 179126049Sminshall code = ntflag; 179226049Sminshall (void) strncpy(ntin, argv[1], 16); 179326049Sminshall ntin[16] = '\0'; 179426049Sminshall if (argc == 2) { 179526049Sminshall ntout[0] = '\0'; 179626049Sminshall return; 179726049Sminshall } 179826049Sminshall (void) strncpy(ntout, argv[2], 16); 179926049Sminshall ntout[16] = '\0'; 180026049Sminshall } 180126049Sminshall 180226049Sminshall char * 180326049Sminshall dotrans(name) 180426049Sminshall char *name; 180526049Sminshall { 180626049Sminshall static char new[MAXPATHLEN]; 180726049Sminshall char *cp1, *cp2 = new; 180826049Sminshall register int i, ostop, found; 180926049Sminshall 181026049Sminshall for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++); 181126049Sminshall for (cp1 = name; *cp1; cp1++) { 181226049Sminshall found = 0; 181326049Sminshall for (i = 0; *(ntin + i) && i < 16; i++) { 181426049Sminshall if (*cp1 == *(ntin + i)) { 181526049Sminshall found++; 181626049Sminshall if (i < ostop) { 181726049Sminshall *cp2++ = *(ntout + i); 181826049Sminshall } 181926049Sminshall break; 182026049Sminshall } 182126049Sminshall } 182226049Sminshall if (!found) { 182326049Sminshall *cp2++ = *cp1; 182426049Sminshall } 182526049Sminshall } 182626049Sminshall *cp2 = '\0'; 182726049Sminshall return(new); 182826049Sminshall } 182926049Sminshall 183026049Sminshall setnmap(argc, argv) 183126049Sminshall int argc; 183226049Sminshall char *argv[]; 183326049Sminshall { 183426049Sminshall char *cp; 183526049Sminshall 183626049Sminshall if (argc == 1) { 183726049Sminshall mapflag = 0; 183826049Sminshall printf("Nmap off.\n"); 183926049Sminshall code = mapflag; 184026049Sminshall return; 184126049Sminshall } 184226049Sminshall if (argc < 3) { 184326497Sminshall (void) strcat(line, " "); 184426049Sminshall printf("(mapout) "); 184526497Sminshall (void) gets(&line[strlen(line)]); 184626049Sminshall makeargv(); 184726049Sminshall argc = margc; 184826049Sminshall argv = margv; 184926049Sminshall } 185026049Sminshall if (argc < 3) { 185126049Sminshall printf("Usage: %s [mapin mapout]\n",argv[0]); 185226049Sminshall code = -1; 185326049Sminshall return; 185426049Sminshall } 185526049Sminshall mapflag = 1; 185626049Sminshall code = 1; 185726049Sminshall cp = index(altarg, ' '); 185826049Sminshall if (proxy) { 185926049Sminshall while(*++cp == ' '); 186026049Sminshall altarg = cp; 186126049Sminshall cp = index(altarg, ' '); 186226049Sminshall } 186326049Sminshall *cp = '\0'; 186426049Sminshall (void) strncpy(mapin, altarg, MAXPATHLEN - 1); 186526049Sminshall while (*++cp == ' '); 186626049Sminshall (void) strncpy(mapout, cp, MAXPATHLEN - 1); 186726049Sminshall } 186826049Sminshall 186926049Sminshall char * 187026049Sminshall domap(name) 187126049Sminshall char *name; 187226049Sminshall { 187326049Sminshall static char new[MAXPATHLEN]; 187426049Sminshall register char *cp1 = name, *cp2 = mapin; 187526049Sminshall char *tp[9], *te[9]; 187636689Scsvsj int i, toks[9], toknum = 0, match = 1; 187726049Sminshall 187826049Sminshall for (i=0; i < 9; ++i) { 187926049Sminshall toks[i] = 0; 188026049Sminshall } 188126049Sminshall while (match && *cp1 && *cp2) { 188226049Sminshall switch (*cp2) { 188326049Sminshall case '\\': 188426049Sminshall if (*++cp2 != *cp1) { 188526049Sminshall match = 0; 188626049Sminshall } 188726049Sminshall break; 188826049Sminshall case '$': 188926049Sminshall if (*(cp2+1) >= '1' && (*cp2+1) <= '9') { 189026049Sminshall if (*cp1 != *(++cp2+1)) { 189126049Sminshall toks[toknum = *cp2 - '1']++; 189226049Sminshall tp[toknum] = cp1; 189326049Sminshall while (*++cp1 && *(cp2+1) 189426049Sminshall != *cp1); 189526049Sminshall te[toknum] = cp1; 189626049Sminshall } 189726049Sminshall cp2++; 189826049Sminshall break; 189926049Sminshall } 190036935Skarels /* FALLTHROUGH */ 190126049Sminshall default: 190226049Sminshall if (*cp2 != *cp1) { 190326049Sminshall match = 0; 190426049Sminshall } 190526049Sminshall break; 190626049Sminshall } 190736689Scsvsj if (match && *cp1) { 190826049Sminshall cp1++; 190926049Sminshall } 191036689Scsvsj if (match && *cp2) { 191126049Sminshall cp2++; 191226049Sminshall } 191326049Sminshall } 191436689Scsvsj if (!match && *cp1) /* last token mismatch */ 191536689Scsvsj { 191636689Scsvsj toks[toknum] = 0; 191736689Scsvsj } 191826049Sminshall cp1 = new; 191926049Sminshall *cp1 = '\0'; 192026049Sminshall cp2 = mapout; 192126049Sminshall while (*cp2) { 192226049Sminshall match = 0; 192326049Sminshall switch (*cp2) { 192426049Sminshall case '\\': 192526049Sminshall if (*(cp2 + 1)) { 192626049Sminshall *cp1++ = *++cp2; 192726049Sminshall } 192826049Sminshall break; 192926049Sminshall case '[': 193026049Sminshall LOOP: 193126049Sminshall if (*++cp2 == '$' && isdigit(*(cp2+1))) { 193226049Sminshall if (*++cp2 == '0') { 193326049Sminshall char *cp3 = name; 193426049Sminshall 193526049Sminshall while (*cp3) { 193626049Sminshall *cp1++ = *cp3++; 193726049Sminshall } 193826049Sminshall match = 1; 193926049Sminshall } 194026049Sminshall else if (toks[toknum = *cp2 - '1']) { 194126049Sminshall char *cp3 = tp[toknum]; 194226049Sminshall 194326049Sminshall while (cp3 != te[toknum]) { 194426049Sminshall *cp1++ = *cp3++; 194526049Sminshall } 194626049Sminshall match = 1; 194726049Sminshall } 194826049Sminshall } 194926049Sminshall else { 195026049Sminshall while (*cp2 && *cp2 != ',' && 195126049Sminshall *cp2 != ']') { 195226049Sminshall if (*cp2 == '\\') { 195326049Sminshall cp2++; 195426049Sminshall } 195526049Sminshall else if (*cp2 == '$' && 195626049Sminshall isdigit(*(cp2+1))) { 195726049Sminshall if (*++cp2 == '0') { 195826049Sminshall char *cp3 = name; 195926049Sminshall 196026049Sminshall while (*cp3) { 196126049Sminshall *cp1++ = *cp3++; 196226049Sminshall } 196326049Sminshall } 196426049Sminshall else if (toks[toknum = 196526049Sminshall *cp2 - '1']) { 196626049Sminshall char *cp3=tp[toknum]; 196726049Sminshall 196826049Sminshall while (cp3 != 196926049Sminshall te[toknum]) { 197026049Sminshall *cp1++ = *cp3++; 197126049Sminshall } 197226049Sminshall } 197326049Sminshall } 197426049Sminshall else if (*cp2) { 197526049Sminshall *cp1++ = *cp2++; 197626049Sminshall } 197726049Sminshall } 197826049Sminshall if (!*cp2) { 197926049Sminshall printf("nmap: unbalanced brackets\n"); 198026049Sminshall return(name); 198126049Sminshall } 198226049Sminshall match = 1; 198326049Sminshall cp2--; 198426049Sminshall } 198526049Sminshall if (match) { 198626049Sminshall while (*++cp2 && *cp2 != ']') { 198726049Sminshall if (*cp2 == '\\' && *(cp2 + 1)) { 198826049Sminshall cp2++; 198926049Sminshall } 199026049Sminshall } 199126049Sminshall if (!*cp2) { 199226049Sminshall printf("nmap: unbalanced brackets\n"); 199326049Sminshall return(name); 199426049Sminshall } 199526049Sminshall break; 199626049Sminshall } 199726049Sminshall switch (*++cp2) { 199826049Sminshall case ',': 199926049Sminshall goto LOOP; 200026049Sminshall case ']': 200126049Sminshall break; 200226049Sminshall default: 200326049Sminshall cp2--; 200426049Sminshall goto LOOP; 200526049Sminshall } 200626049Sminshall break; 200726049Sminshall case '$': 200826049Sminshall if (isdigit(*(cp2 + 1))) { 200926049Sminshall if (*++cp2 == '0') { 201026049Sminshall char *cp3 = name; 201126049Sminshall 201226049Sminshall while (*cp3) { 201326049Sminshall *cp1++ = *cp3++; 201426049Sminshall } 201526049Sminshall } 201626049Sminshall else if (toks[toknum = *cp2 - '1']) { 201726049Sminshall char *cp3 = tp[toknum]; 201826049Sminshall 201926049Sminshall while (cp3 != te[toknum]) { 202026049Sminshall *cp1++ = *cp3++; 202126049Sminshall } 202226049Sminshall } 202326049Sminshall break; 202426049Sminshall } 202526049Sminshall /* intentional drop through */ 202626049Sminshall default: 202726049Sminshall *cp1++ = *cp2; 202826049Sminshall break; 202926049Sminshall } 203026049Sminshall cp2++; 203126049Sminshall } 203226049Sminshall *cp1 = '\0'; 203326049Sminshall if (!*new) { 203426049Sminshall return(name); 203526049Sminshall } 203626049Sminshall return(new); 203726049Sminshall } 203826049Sminshall 203926049Sminshall setsunique() 204026049Sminshall { 204126049Sminshall sunique = !sunique; 204226049Sminshall printf("Store unique %s.\n", onoff(sunique)); 204326049Sminshall code = sunique; 204426049Sminshall } 204526049Sminshall 204626049Sminshall setrunique() 204726049Sminshall { 204826049Sminshall runique = !runique; 204926049Sminshall printf("Receive unique %s.\n", onoff(runique)); 205026049Sminshall code = runique; 205126049Sminshall } 205226049Sminshall 205326049Sminshall /* change directory to perent directory */ 205426049Sminshall cdup() 205526049Sminshall { 205637224Skarels if (command("CDUP") == ERROR && code == 500) { 205737224Skarels if (verbose) 205837224Skarels printf("CDUP command not recognized, trying XCUP\n"); 205937224Skarels (void) command("XCUP"); 206037224Skarels } 206126049Sminshall } 206226049Sminshall 206337224Skarels /* restart transfer at specific point */ 206437224Skarels restart(argc, argv) 206537224Skarels int argc; 206637224Skarels char *argv[]; 206737224Skarels { 206837224Skarels extern long atol(); 206937224Skarels if (argc != 2) 207037224Skarels printf("restart: offset not specified\n"); 207137224Skarels else { 207237224Skarels restart_point = atol(argv[1]); 207337224Skarels printf("restarting at %ld. %s\n", restart_point, 207437224Skarels "execute get, put or append to initiate transfer"); 207537224Skarels } 207637224Skarels } 207736935Skarels 207836935Skarels /* show remote system type */ 207936935Skarels syst() 208036935Skarels { 208136935Skarels (void) command("SYST"); 208236935Skarels } 208336935Skarels 208426049Sminshall macdef(argc, argv) 208526049Sminshall int argc; 208626049Sminshall char *argv[]; 208726049Sminshall { 208826049Sminshall char *tmp; 208926049Sminshall int c; 209026049Sminshall 209126049Sminshall if (macnum == 16) { 209226049Sminshall printf("Limit of 16 macros have already been defined\n"); 209326049Sminshall code = -1; 209426049Sminshall return; 209526049Sminshall } 209626049Sminshall if (argc < 2) { 209726497Sminshall (void) strcat(line, " "); 209826049Sminshall printf("(macro name) "); 209926497Sminshall (void) gets(&line[strlen(line)]); 210026049Sminshall makeargv(); 210126049Sminshall argc = margc; 210226049Sminshall argv = margv; 210326049Sminshall } 210426049Sminshall if (argc != 2) { 210526049Sminshall printf("Usage: %s macro_name\n",argv[0]); 210626049Sminshall code = -1; 210726049Sminshall return; 210826049Sminshall } 210926049Sminshall if (interactive) { 211026049Sminshall printf("Enter macro line by line, terminating it with a null line\n"); 211126049Sminshall } 211226497Sminshall (void) strncpy(macros[macnum].mac_name, argv[1], 8); 211326049Sminshall if (macnum == 0) { 211426049Sminshall macros[macnum].mac_start = macbuf; 211526049Sminshall } 211626049Sminshall else { 211726049Sminshall macros[macnum].mac_start = macros[macnum - 1].mac_end + 1; 211826049Sminshall } 211926049Sminshall tmp = macros[macnum].mac_start; 212026049Sminshall while (tmp != macbuf+4096) { 212126049Sminshall if ((c = getchar()) == EOF) { 212226049Sminshall printf("macdef:end of file encountered\n"); 212326049Sminshall code = -1; 212426049Sminshall return; 212526049Sminshall } 212626049Sminshall if ((*tmp = c) == '\n') { 212726049Sminshall if (tmp == macros[macnum].mac_start) { 212826049Sminshall macros[macnum++].mac_end = tmp; 212926049Sminshall code = 0; 213026049Sminshall return; 213126049Sminshall } 213226049Sminshall if (*(tmp-1) == '\0') { 213326049Sminshall macros[macnum++].mac_end = tmp - 1; 213426049Sminshall code = 0; 213526049Sminshall return; 213626049Sminshall } 213726049Sminshall *tmp = '\0'; 213826049Sminshall } 213926049Sminshall tmp++; 214026049Sminshall } 214126049Sminshall while (1) { 214236935Skarels while ((c = getchar()) != '\n' && c != EOF) 214336935Skarels /* LOOP */; 214426049Sminshall if (c == EOF || getchar() == '\n') { 214526049Sminshall printf("Macro not defined - 4k buffer exceeded\n"); 214626049Sminshall code = -1; 214726049Sminshall return; 214826049Sminshall } 214926049Sminshall } 215026049Sminshall } 215136935Skarels 215236935Skarels /* 215336935Skarels * get size of file on remote machine 215436935Skarels */ 215536935Skarels sizecmd(argc, argv) 215636935Skarels char *argv[]; 215736935Skarels { 215836935Skarels 215936935Skarels if (argc < 2) { 216036935Skarels (void) strcat(line, " "); 216136935Skarels printf("(filename) "); 216236935Skarels (void) gets(&line[strlen(line)]); 216336935Skarels makeargv(); 216436935Skarels argc = margc; 216536935Skarels argv = margv; 216636935Skarels } 216736935Skarels if (argc < 2) { 216836935Skarels printf("usage:%s filename\n", argv[0]); 216936935Skarels code = -1; 217036935Skarels return; 217136935Skarels } 217236935Skarels (void) command("SIZE %s", argv[1]); 217336935Skarels } 217436935Skarels 217536935Skarels /* 217636935Skarels * get last modification time of file on remote machine 217736935Skarels */ 217836935Skarels modtime(argc, argv) 217936935Skarels char *argv[]; 218036935Skarels { 218136935Skarels int overbose; 218236935Skarels 218336935Skarels if (argc < 2) { 218436935Skarels (void) strcat(line, " "); 218536935Skarels printf("(filename) "); 218636935Skarels (void) gets(&line[strlen(line)]); 218736935Skarels makeargv(); 218836935Skarels argc = margc; 218936935Skarels argv = margv; 219036935Skarels } 219136935Skarels if (argc < 2) { 219236935Skarels printf("usage:%s filename\n", argv[0]); 219336935Skarels code = -1; 219436935Skarels return; 219536935Skarels } 219636940Skarels overbose = verbose; 219736940Skarels if (debug == 0) 219836940Skarels verbose = -1; 219936935Skarels if (command("MDTM %s", argv[1]) == COMPLETE) { 220036935Skarels int yy, mo, day, hour, min, sec; 220136935Skarels sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo, 220236935Skarels &day, &hour, &min, &sec); 220336935Skarels /* might want to print this in local time */ 220436935Skarels printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1], 220536935Skarels mo, day, yy, hour, min, sec); 220636935Skarels } else 220736935Skarels fputs(reply_string, stdout); 220836935Skarels verbose = overbose; 220936935Skarels } 221036935Skarels 221136935Skarels /* 221237224Skarels * show status on reomte machine 221336935Skarels */ 221436935Skarels rmtstatus(argc, argv) 221536935Skarels char *argv[]; 221636935Skarels { 221736935Skarels (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]); 221836935Skarels } 221937224Skarels 222037224Skarels /* 222137224Skarels * get file if modtime is more recent than current file 222237224Skarels */ 222337224Skarels newer(argc, argv) 222437224Skarels char *argv[]; 222537224Skarels { 222637224Skarels if (getit(argc, argv, -1, "w")) 222737224Skarels printf("Local file \"%s\" is newer than remote file \"%s\"\n", 222837224Skarels argv[1], argv[2]); 222937224Skarels } 2230