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*37458Skarels static char sccsid[] = "@(#)cmds.c 5.18 (Berkeley) 04/20/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" 40*37458Skarels #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(); 49*37458Skarels extern int allbinary; 5037224Skarels extern off_t restart_point; 5136935Skarels extern char reply_string[]; 5236935Skarels 5326049Sminshall char *mname; 5426049Sminshall jmp_buf jabort; 5526049Sminshall char *dotrans(), *domap(); 5610294Ssam 5710294Ssam /* 5810294Ssam * Connect to peer server and 5910294Ssam * auto-login, if possible. 6010294Ssam */ 6110294Ssam setpeer(argc, argv) 6210294Ssam int argc; 6310294Ssam char *argv[]; 6410294Ssam { 6525903Skarels char *host, *hookup(); 6610294Ssam int port; 6710294Ssam 6810294Ssam if (connected) { 6926049Sminshall printf("Already connected to %s, use close first.\n", 7010294Ssam hostname); 7126049Sminshall code = -1; 7210294Ssam return; 7310294Ssam } 7410294Ssam if (argc < 2) { 7526497Sminshall (void) strcat(line, " "); 7610294Ssam printf("(to) "); 7726497Sminshall (void) gets(&line[strlen(line)]); 7810294Ssam makeargv(); 7910294Ssam argc = margc; 8010294Ssam argv = margv; 8110294Ssam } 8210294Ssam if (argc > 3) { 8310294Ssam printf("usage: %s host-name [port]\n", argv[0]); 8426049Sminshall code = -1; 8510294Ssam return; 8610294Ssam } 8710294Ssam port = sp->s_port; 8810294Ssam if (argc > 2) { 8911218Ssam port = atoi(argv[2]); 9010294Ssam if (port <= 0) { 9111218Ssam printf("%s: bad port number-- %s\n", argv[1], argv[2]); 9211218Ssam printf ("usage: %s host-name [port]\n", argv[0]); 9326049Sminshall code = -1; 9410294Ssam return; 9510294Ssam } 9610294Ssam port = htons(port); 9710294Ssam } 9810294Ssam host = hookup(argv[1], port); 9910294Ssam if (host) { 10037228Skarels int overbose; 10137228Skarels 10210294Ssam connected = 1; 10337228Skarels if (autologin) 10437228Skarels (void) login(argv[1]); 10536940Skarels 10636935Skarels #if defined(unix) && NBBY == 8 10736935Skarels /* 10836935Skarels * this ifdef is to keep someone form "porting" this to an incompatible 10936935Skarels * system and not checking this out. This way they have to think about it. 11036935Skarels */ 11137228Skarels overbose = verbose; 11237228Skarels if (debug == 0) 11337228Skarels verbose = -1; 114*37458Skarels allbinary = 0; 11537228Skarels if (command("SYST") == COMPLETE && overbose) { 11637228Skarels register char *cp, c; 11737228Skarels cp = index(reply_string+4, ' '); 11837228Skarels if (cp == NULL) 11937228Skarels cp = index(reply_string+4, '\r'); 12037228Skarels if (cp) { 12137228Skarels if (cp[-1] == '.') 12237228Skarels cp--; 12337228Skarels c = *cp; 12437228Skarels *cp = '\0'; 12537228Skarels } 12636935Skarels 12737228Skarels printf("Remote system type is %s.\n", 12837228Skarels reply_string+4); 12937228Skarels if (cp) 13037228Skarels *cp = c; 13137228Skarels } 13237228Skarels if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) { 13337228Skarels setbinary(); 134*37458Skarels allbinary = 1; 13537228Skarels if (overbose) 13637228Skarels printf("Using %s mode to transfer files.\n", 13737228Skarels typename); 13837228Skarels } else if (overbose && 13937228Skarels !strncmp(reply_string, "215 TOPS20", 10)) { 14037228Skarels printf( 14136940Skarels "Remember to set tenex mode when transfering binary files from this machine.\n"); 14237228Skarels } 14337228Skarels verbose = overbose; 14436935Skarels #endif /* unix */ 14510294Ssam } 14610294Ssam } 14710294Ssam 14810294Ssam struct types { 14910294Ssam char *t_name; 15010294Ssam char *t_mode; 15110294Ssam int t_type; 15211218Ssam char *t_arg; 15310294Ssam } types[] = { 15411218Ssam { "ascii", "A", TYPE_A, 0 }, 15511218Ssam { "binary", "I", TYPE_I, 0 }, 15611218Ssam { "image", "I", TYPE_I, 0 }, 15711218Ssam { "ebcdic", "E", TYPE_E, 0 }, 15811218Ssam { "tenex", "L", TYPE_L, bytename }, 15910294Ssam 0 16010294Ssam }; 16110294Ssam 16210294Ssam /* 16310294Ssam * Set transfer type. 16410294Ssam */ 16510294Ssam settype(argc, argv) 16610294Ssam char *argv[]; 16710294Ssam { 16810294Ssam register struct types *p; 16911218Ssam int comret; 17010294Ssam 17110294Ssam if (argc > 2) { 17210294Ssam char *sep; 17310294Ssam 17410294Ssam printf("usage: %s [", argv[0]); 17510294Ssam sep = " "; 17610294Ssam for (p = types; p->t_name; p++) { 17710294Ssam printf("%s%s", sep, p->t_name); 17810294Ssam if (*sep == ' ') 17910294Ssam sep = " | "; 18010294Ssam } 18110294Ssam printf(" ]\n"); 18226049Sminshall code = -1; 18310294Ssam return; 18410294Ssam } 18510294Ssam if (argc < 2) { 18610294Ssam printf("Using %s mode to transfer files.\n", typename); 18726049Sminshall code = 0; 18810294Ssam return; 18910294Ssam } 19010294Ssam for (p = types; p->t_name; p++) 19110294Ssam if (strcmp(argv[1], p->t_name) == 0) 19210294Ssam break; 19310294Ssam if (p->t_name == 0) { 19410294Ssam printf("%s: unknown mode\n", argv[1]); 19526049Sminshall code = -1; 19610294Ssam return; 19710294Ssam } 19811218Ssam if ((p->t_arg != NULL) && (*(p->t_arg) != '\0')) 19911218Ssam comret = command ("TYPE %s %s", p->t_mode, p->t_arg); 20011218Ssam else 20111218Ssam comret = command("TYPE %s", p->t_mode); 20211218Ssam if (comret == COMPLETE) { 20326497Sminshall (void) strcpy(typename, p->t_name); 20410294Ssam type = p->t_type; 20510294Ssam } 20610294Ssam } 20710294Ssam 20810294Ssam /* 20910294Ssam * Set binary transfer type. 21010294Ssam */ 21110294Ssam /*VARARGS*/ 21210294Ssam setbinary() 21310294Ssam { 21410294Ssam 21510294Ssam call(settype, "type", "binary", 0); 21610294Ssam } 21710294Ssam 21810294Ssam /* 21910294Ssam * Set ascii transfer type. 22010294Ssam */ 22110294Ssam /*VARARGS*/ 22210294Ssam setascii() 22310294Ssam { 22410294Ssam 22510294Ssam call(settype, "type", "ascii", 0); 22610294Ssam } 22710294Ssam 22810294Ssam /* 22910294Ssam * Set tenex transfer type. 23010294Ssam */ 23110294Ssam /*VARARGS*/ 23210294Ssam settenex() 23310294Ssam { 23410294Ssam 23510294Ssam call(settype, "type", "tenex", 0); 23610294Ssam } 23710294Ssam 23810294Ssam /* 23910294Ssam * Set ebcdic transfer type. 24010294Ssam */ 24110294Ssam /*VARARGS*/ 24210294Ssam setebcdic() 24310294Ssam { 24410294Ssam 24510294Ssam call(settype, "type", "ebcdic", 0); 24610294Ssam } 24710294Ssam 24810294Ssam /* 24910294Ssam * Set file transfer mode. 25010294Ssam */ 25126497Sminshall /*ARGSUSED*/ 25210294Ssam setmode(argc, argv) 25310294Ssam char *argv[]; 25410294Ssam { 25510294Ssam 25610294Ssam printf("We only support %s mode, sorry.\n", modename); 25726049Sminshall code = -1; 25810294Ssam } 25910294Ssam 26010294Ssam /* 26110294Ssam * Set file transfer format. 26210294Ssam */ 26326497Sminshall /*ARGSUSED*/ 26410294Ssam setform(argc, argv) 26510294Ssam char *argv[]; 26610294Ssam { 26710294Ssam 26810294Ssam printf("We only support %s format, sorry.\n", formname); 26926049Sminshall code = -1; 27010294Ssam } 27110294Ssam 27210294Ssam /* 27310294Ssam * Set file transfer structure. 27410294Ssam */ 27526497Sminshall /*ARGSUSED*/ 27610294Ssam setstruct(argc, argv) 27710294Ssam char *argv[]; 27810294Ssam { 27910294Ssam 28010294Ssam printf("We only support %s structure, sorry.\n", structname); 28126049Sminshall code = -1; 28210294Ssam } 28310294Ssam 28418286Sralph /* 28518286Sralph * Send a single file. 28618286Sralph */ 28710294Ssam put(argc, argv) 28811756Ssam int argc; 28910294Ssam char *argv[]; 29010294Ssam { 29111650Ssam char *cmd; 29226049Sminshall int loc = 0; 29337225Skarels char *oldargv1, *oldargv2; 29411650Ssam 29526049Sminshall if (argc == 2) { 29626049Sminshall argc++; 29726049Sminshall argv[2] = argv[1]; 29826049Sminshall loc++; 29926049Sminshall } 30010294Ssam if (argc < 2) { 30126497Sminshall (void) strcat(line, " "); 30210294Ssam printf("(local-file) "); 30326497Sminshall (void) gets(&line[strlen(line)]); 30410294Ssam makeargv(); 30510294Ssam argc = margc; 30610294Ssam argv = margv; 30710294Ssam } 30810294Ssam if (argc < 2) { 30910294Ssam usage: 31026049Sminshall printf("usage:%s local-file remote-file\n", argv[0]); 31126049Sminshall code = -1; 31210294Ssam return; 31310294Ssam } 31410294Ssam if (argc < 3) { 31526497Sminshall (void) strcat(line, " "); 31610294Ssam printf("(remote-file) "); 31726497Sminshall (void) gets(&line[strlen(line)]); 31810294Ssam makeargv(); 31910294Ssam argc = margc; 32010294Ssam argv = margv; 32110294Ssam } 32210294Ssam if (argc < 3) 32310294Ssam goto usage; 32425908Smckusick oldargv1 = argv[1]; 32537225Skarels oldargv2 = argv[2]; 32626049Sminshall if (!globulize(&argv[1])) { 32726049Sminshall code = -1; 32811353Ssam return; 32926049Sminshall } 33025908Smckusick /* 33125908Smckusick * If "globulize" modifies argv[1], and argv[2] is a copy of 33225908Smckusick * the old argv[1], make it a copy of the new argv[1]. 33325908Smckusick */ 33426049Sminshall if (argv[1] != oldargv1 && argv[2] == oldargv1) { 33525908Smckusick argv[2] = argv[1]; 33626049Sminshall } 33726049Sminshall cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR"); 33826049Sminshall if (loc && ntflag) { 33926049Sminshall argv[2] = dotrans(argv[2]); 34026049Sminshall } 34126049Sminshall if (loc && mapflag) { 34226049Sminshall argv[2] = domap(argv[2]); 34326049Sminshall } 34437225Skarels sendrequest(cmd, argv[1], argv[2], 34537225Skarels argv[1] != oldargv1 || argv[2] != oldargv2); 34610294Ssam } 34710294Ssam 34810294Ssam /* 34911756Ssam * Send multiple files. 35010294Ssam */ 35111353Ssam mput(argc, argv) 35211353Ssam char *argv[]; 35311353Ssam { 35413212Ssam register int i; 35526049Sminshall int ointer, (*oldintr)(), mabort(); 35626049Sminshall extern jmp_buf jabort; 35726049Sminshall char *tp; 35811353Ssam 35911650Ssam if (argc < 2) { 36026497Sminshall (void) strcat(line, " "); 36111650Ssam printf("(local-files) "); 36226497Sminshall (void) gets(&line[strlen(line)]); 36311650Ssam makeargv(); 36411650Ssam argc = margc; 36511650Ssam argv = margv; 36611353Ssam } 36711353Ssam if (argc < 2) { 36826049Sminshall printf("usage:%s local-files\n", argv[0]); 36926049Sminshall code = -1; 37011353Ssam return; 37111353Ssam } 37226049Sminshall mname = argv[0]; 37326049Sminshall mflag = 1; 37426049Sminshall oldintr = signal(SIGINT, mabort); 37526049Sminshall (void) setjmp(jabort); 37626049Sminshall if (proxy) { 37726049Sminshall char *cp, *tp2, tmpbuf[MAXPATHLEN]; 37826049Sminshall 37926497Sminshall while ((cp = remglob(argv,0)) != NULL) { 38026049Sminshall if (*cp == 0) { 38126049Sminshall mflag = 0; 38226049Sminshall continue; 38326049Sminshall } 38426049Sminshall if (mflag && confirm(argv[0], cp)) { 38526049Sminshall tp = cp; 38626049Sminshall if (mcase) { 38726049Sminshall while (*tp && !islower(*tp)) { 38826049Sminshall tp++; 38926049Sminshall } 39026049Sminshall if (!*tp) { 39126049Sminshall tp = cp; 39226049Sminshall tp2 = tmpbuf; 39326049Sminshall while ((*tp2 = *tp) != NULL) { 39426049Sminshall if (isupper(*tp2)) { 39526049Sminshall *tp2 = 'a' + *tp2 - 'A'; 39626049Sminshall } 39726049Sminshall tp++; 39826049Sminshall tp2++; 39926049Sminshall } 40026049Sminshall } 40126049Sminshall tp = tmpbuf; 40226049Sminshall } 40326049Sminshall if (ntflag) { 40426049Sminshall tp = dotrans(tp); 40526049Sminshall } 40626049Sminshall if (mapflag) { 40726049Sminshall tp = domap(tp); 40826049Sminshall } 40937225Skarels sendrequest((sunique) ? "STOU" : "STOR", 41037225Skarels cp, tp, cp != tp || !interactive); 41126049Sminshall if (!mflag && fromatty) { 41226049Sminshall ointer = interactive; 41326049Sminshall interactive = 1; 41426049Sminshall if (confirm("Continue with","mput")) { 41526049Sminshall mflag++; 41626049Sminshall } 41726049Sminshall interactive = ointer; 41826049Sminshall } 41926049Sminshall } 42026049Sminshall } 42126049Sminshall (void) signal(SIGINT, oldintr); 42226049Sminshall mflag = 0; 42326049Sminshall return; 42426049Sminshall } 42513212Ssam for (i = 1; i < argc; i++) { 42613212Ssam register char **cpp, **gargs; 42713212Ssam 42813212Ssam if (!doglob) { 42926049Sminshall if (mflag && confirm(argv[0], argv[i])) { 43026049Sminshall tp = (ntflag) ? dotrans(argv[i]) : argv[i]; 43126049Sminshall tp = (mapflag) ? domap(tp) : tp; 43226049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 43337225Skarels argv[i], tp, tp != argv[i] || !interactive); 43426049Sminshall if (!mflag && fromatty) { 43526049Sminshall ointer = interactive; 43626049Sminshall interactive = 1; 43726049Sminshall if (confirm("Continue with","mput")) { 43826049Sminshall mflag++; 43926049Sminshall } 44026049Sminshall interactive = ointer; 44126049Sminshall } 44226049Sminshall } 44313212Ssam continue; 44413212Ssam } 44513212Ssam gargs = glob(argv[i]); 44611650Ssam if (globerr != NULL) { 44711650Ssam printf("%s\n", globerr); 44836421Sbostic if (gargs) { 44911650Ssam blkfree(gargs); 45036421Sbostic free(gargs); 45136421Sbostic } 45213212Ssam continue; 45311353Ssam } 45426049Sminshall for (cpp = gargs; cpp && *cpp != NULL; cpp++) { 45526049Sminshall if (mflag && confirm(argv[0], *cpp)) { 45626049Sminshall tp = (ntflag) ? dotrans(*cpp) : *cpp; 45726049Sminshall tp = (mapflag) ? domap(tp) : tp; 45826049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 45937225Skarels *cpp, tp, *cpp != tp || !interactive); 46026049Sminshall if (!mflag && fromatty) { 46126049Sminshall ointer = interactive; 46226049Sminshall interactive = 1; 46326049Sminshall if (confirm("Continue with","mput")) { 46426049Sminshall mflag++; 46526049Sminshall } 46626049Sminshall interactive = ointer; 46726049Sminshall } 46826049Sminshall } 46926049Sminshall } 47036421Sbostic if (gargs != NULL) { 47113212Ssam blkfree(gargs); 47236421Sbostic free(gargs); 47336421Sbostic } 47411353Ssam } 47526049Sminshall (void) signal(SIGINT, oldintr); 47626049Sminshall mflag = 0; 47711353Ssam } 47811353Ssam 47937224Skarels reget(argc, argv) 48037224Skarels char *argv[]; 48137224Skarels { 48237224Skarels (void) getit(argc, argv, 1, "r+w"); 48337224Skarels } 48436935Skarels 48537224Skarels get(argc, argv) 48637224Skarels char *argv[]; 48737224Skarels { 48837224Skarels (void) getit(argc, argv, 0, restart_point ? "r+w" : "w" ); 48937224Skarels } 49037224Skarels 49111353Ssam /* 49211353Ssam * Receive one file. 49311353Ssam */ 49437224Skarels getit(argc, argv, restartit, mode) 49510294Ssam char *argv[]; 49637224Skarels char *mode; 49710294Ssam { 49826049Sminshall int loc = 0; 49937225Skarels char *oldargv1, *oldargv2; 50010294Ssam 50126049Sminshall if (argc == 2) { 50226049Sminshall argc++; 50326049Sminshall argv[2] = argv[1]; 50426049Sminshall loc++; 50526049Sminshall } 50610294Ssam if (argc < 2) { 50726497Sminshall (void) strcat(line, " "); 50810294Ssam printf("(remote-file) "); 50926497Sminshall (void) gets(&line[strlen(line)]); 51010294Ssam makeargv(); 51110294Ssam argc = margc; 51210294Ssam argv = margv; 51310294Ssam } 51410294Ssam if (argc < 2) { 51510294Ssam usage: 51626049Sminshall printf("usage: %s remote-file [ local-file ]\n", argv[0]); 51726049Sminshall code = -1; 51837224Skarels return (0); 51910294Ssam } 52010294Ssam if (argc < 3) { 52126497Sminshall (void) strcat(line, " "); 52210294Ssam printf("(local-file) "); 52326497Sminshall (void) gets(&line[strlen(line)]); 52410294Ssam makeargv(); 52510294Ssam argc = margc; 52610294Ssam argv = margv; 52710294Ssam } 52810294Ssam if (argc < 3) 52910294Ssam goto usage; 53037225Skarels oldargv1 = argv[1]; 53137225Skarels oldargv2 = argv[2]; 53226049Sminshall if (!globulize(&argv[2])) { 53326049Sminshall code = -1; 53437224Skarels return (0); 53526049Sminshall } 53626049Sminshall if (loc && mcase) { 53726049Sminshall char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN]; 53826049Sminshall 53926049Sminshall while (*tp && !islower(*tp)) { 54026049Sminshall tp++; 54126049Sminshall } 54226049Sminshall if (!*tp) { 54326049Sminshall tp = argv[2]; 54426049Sminshall tp2 = tmpbuf; 54526049Sminshall while ((*tp2 = *tp) != NULL) { 54626049Sminshall if (isupper(*tp2)) { 54726049Sminshall *tp2 = 'a' + *tp2 - 'A'; 54826049Sminshall } 54926049Sminshall tp++; 55026049Sminshall tp2++; 55126049Sminshall } 55226049Sminshall argv[2] = tmpbuf; 55326049Sminshall } 55426049Sminshall } 55536940Skarels if (loc && ntflag) 55626049Sminshall argv[2] = dotrans(argv[2]); 55736940Skarels if (loc && mapflag) 55826049Sminshall argv[2] = domap(argv[2]); 55937224Skarels if (restartit) { 56037224Skarels struct stat stbuf; 56137224Skarels int ret; 56237224Skarels 56337224Skarels ret = stat(argv[2], &stbuf); 56437224Skarels if (restartit == 1) { 56537224Skarels if (ret < 0) { 56637224Skarels perror(argv[2]); 56737224Skarels return (0); 56837224Skarels } 56937224Skarels restart_point = stbuf.st_size; 57037224Skarels } else { 57137224Skarels if (ret == 0) { 57237224Skarels int overbose; 57337224Skarels 57437224Skarels overbose = verbose; 57537224Skarels if (debug == 0) 57637224Skarels verbose = -1; 57737224Skarels if (command("MDTM %s", argv[1]) == COMPLETE) { 57837224Skarels int yy, mo, day, hour, min, sec; 57937224Skarels struct tm *tm; 58037224Skarels verbose = overbose; 58137224Skarels sscanf(reply_string, 58237224Skarels "%*s %04d%02d%02d%02d%02d%02d", 58337224Skarels &yy, &mo, &day, &hour, &min, &sec); 58437224Skarels tm = gmtime(&stbuf.st_mtime); 58537224Skarels tm->tm_mon++; 58637224Skarels if (tm->tm_year > yy%100) 58737224Skarels return (1); 58837224Skarels else if (tm->tm_year == yy%100) { 58937224Skarels if (tm->tm_mon > mo) 59037224Skarels return (1); 59137224Skarels } else if (tm->tm_mon == mo) { 59237224Skarels if (tm->tm_mday > day) 59337224Skarels return (1); 59437224Skarels } else if (tm->tm_mday == day) { 59537224Skarels if (tm->tm_hour > hour) 59637224Skarels return (1); 59737224Skarels } else if (tm->tm_hour == hour) { 59837224Skarels if (tm->tm_min > min) 59937224Skarels return (1); 60037224Skarels } else if (tm->tm_min == min) { 60137224Skarels if (tm->tm_sec > sec) 60237224Skarels return (1); 60337224Skarels } 60437224Skarels } else { 60537224Skarels fputs(reply_string, stdout); 60637224Skarels verbose = overbose; 60737224Skarels return (0); 60837224Skarels } 60937224Skarels } 61037224Skarels } 61137224Skarels } 61237224Skarels 61337225Skarels recvrequest("RETR", argv[2], argv[1], mode, 61437225Skarels argv[1] != oldargv1 || argv[2] != oldargv2); 61537224Skarels restart_point = 0; 61637224Skarels return (0); 61710294Ssam } 61810294Ssam 61926049Sminshall mabort() 62026049Sminshall { 62126049Sminshall int ointer; 62226049Sminshall extern jmp_buf jabort; 62326049Sminshall 62426049Sminshall printf("\n"); 62526049Sminshall (void) fflush(stdout); 62626049Sminshall if (mflag && fromatty) { 62726049Sminshall ointer = interactive; 62826049Sminshall interactive = 1; 62926049Sminshall if (confirm("Continue with", mname)) { 63026049Sminshall interactive = ointer; 63126049Sminshall longjmp(jabort,0); 63226049Sminshall } 63326049Sminshall interactive = ointer; 63426049Sminshall } 63526049Sminshall mflag = 0; 63626049Sminshall longjmp(jabort,0); 63726049Sminshall } 63826049Sminshall 63911353Ssam /* 64011353Ssam * Get multiple files. 64111353Ssam */ 64211353Ssam mget(argc, argv) 64311353Ssam char *argv[]; 64411353Ssam { 64526049Sminshall char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN]; 64626049Sminshall int ointer, (*oldintr)(), mabort(); 64726049Sminshall extern jmp_buf jabort; 64811353Ssam 64911353Ssam if (argc < 2) { 65026497Sminshall (void) strcat(line, " "); 65111756Ssam printf("(remote-files) "); 65226497Sminshall (void) gets(&line[strlen(line)]); 65311353Ssam makeargv(); 65411353Ssam argc = margc; 65511353Ssam argv = margv; 65611353Ssam } 65711353Ssam if (argc < 2) { 65826049Sminshall printf("usage:%s remote-files\n", argv[0]); 65926049Sminshall code = -1; 66011353Ssam return; 66111353Ssam } 66226049Sminshall mname = argv[0]; 66326049Sminshall mflag = 1; 66426049Sminshall oldintr = signal(SIGINT,mabort); 66526049Sminshall (void) setjmp(jabort); 66626497Sminshall while ((cp = remglob(argv,proxy)) != NULL) { 66726049Sminshall if (*cp == '\0') { 66826049Sminshall mflag = 0; 66926049Sminshall continue; 67026049Sminshall } 67126049Sminshall if (mflag && confirm(argv[0], cp)) { 67226049Sminshall tp = cp; 67326049Sminshall if (mcase) { 67426049Sminshall while (*tp && !islower(*tp)) { 67526049Sminshall tp++; 67626049Sminshall } 67726049Sminshall if (!*tp) { 67826049Sminshall tp = cp; 67926049Sminshall tp2 = tmpbuf; 68026049Sminshall while ((*tp2 = *tp) != NULL) { 68126049Sminshall if (isupper(*tp2)) { 68226049Sminshall *tp2 = 'a' + *tp2 - 'A'; 68326049Sminshall } 68426049Sminshall tp++; 68526049Sminshall tp2++; 68626049Sminshall } 68726049Sminshall } 68826049Sminshall tp = tmpbuf; 68926049Sminshall } 69026049Sminshall if (ntflag) { 69126049Sminshall tp = dotrans(tp); 69226049Sminshall } 69326049Sminshall if (mapflag) { 69426049Sminshall tp = domap(tp); 69526049Sminshall } 69637225Skarels recvrequest("RETR", tp, cp, "w", 69737225Skarels tp != cp || !interactive); 69826049Sminshall if (!mflag && fromatty) { 69926049Sminshall ointer = interactive; 70026049Sminshall interactive = 1; 70126049Sminshall if (confirm("Continue with","mget")) { 70226049Sminshall mflag++; 70326049Sminshall } 70426049Sminshall interactive = ointer; 70526049Sminshall } 70626049Sminshall } 70726049Sminshall } 70826049Sminshall (void) signal(SIGINT,oldintr); 70926049Sminshall mflag = 0; 71011650Ssam } 71111650Ssam 71211650Ssam char * 71326497Sminshall remglob(argv,doswitch) 71411650Ssam char *argv[]; 71526497Sminshall int doswitch; 71611650Ssam { 71711756Ssam char temp[16]; 71811650Ssam static char buf[MAXPATHLEN]; 71911650Ssam static FILE *ftemp = NULL; 72011650Ssam static char **args; 72113212Ssam int oldverbose, oldhash; 72211756Ssam char *cp, *mode; 72311650Ssam 72426049Sminshall if (!mflag) { 72526049Sminshall if (!doglob) { 72626049Sminshall args = NULL; 72726049Sminshall } 72826049Sminshall else { 72926049Sminshall if (ftemp) { 73026497Sminshall (void) fclose(ftemp); 73126049Sminshall ftemp = NULL; 73226049Sminshall } 73326049Sminshall } 73426049Sminshall return(NULL); 73526049Sminshall } 73611650Ssam if (!doglob) { 73711756Ssam if (args == NULL) 73811650Ssam args = argv; 73911650Ssam if ((cp = *++args) == NULL) 74011650Ssam args = NULL; 74111650Ssam return (cp); 74211353Ssam } 74311650Ssam if (ftemp == NULL) { 744*37458Skarels (void) strcpy(temp, _PATH_TMP); 74526497Sminshall (void) mktemp(temp); 74611650Ssam oldverbose = verbose, verbose = 0; 74713212Ssam oldhash = hash, hash = 0; 74826049Sminshall if (doswitch) { 74926049Sminshall pswitch(!proxy); 75026049Sminshall } 75111756Ssam for (mode = "w"; *++argv != NULL; mode = "a") 75237225Skarels recvrequest ("NLST", temp, *argv, mode, 0); 75326049Sminshall if (doswitch) { 75426049Sminshall pswitch(!proxy); 75526049Sminshall } 75613212Ssam verbose = oldverbose; hash = oldhash; 75711650Ssam ftemp = fopen(temp, "r"); 75826497Sminshall (void) unlink(temp); 75911650Ssam if (ftemp == NULL) { 76011650Ssam printf("can't find list of remote files, oops\n"); 76111756Ssam return (NULL); 76211353Ssam } 76311353Ssam } 76411650Ssam if (fgets(buf, sizeof (buf), ftemp) == NULL) { 76526497Sminshall (void) fclose(ftemp), ftemp = NULL; 76611650Ssam return (NULL); 76711353Ssam } 76811650Ssam if ((cp = index(buf, '\n')) != NULL) 76911650Ssam *cp = '\0'; 77011650Ssam return (buf); 77111353Ssam } 77211353Ssam 77310294Ssam char * 77410294Ssam onoff(bool) 77510294Ssam int bool; 77610294Ssam { 77710294Ssam 77810294Ssam return (bool ? "on" : "off"); 77910294Ssam } 78010294Ssam 78110294Ssam /* 78210294Ssam * Show status. 78310294Ssam */ 78426497Sminshall /*ARGSUSED*/ 78510294Ssam status(argc, argv) 78610294Ssam char *argv[]; 78710294Ssam { 78826049Sminshall int i; 78910294Ssam 79010294Ssam if (connected) 79110294Ssam printf("Connected to %s.\n", hostname); 79210294Ssam else 79310294Ssam printf("Not connected.\n"); 79426049Sminshall if (!proxy) { 79526049Sminshall pswitch(1); 79626049Sminshall if (connected) { 79726049Sminshall printf("Connected for proxy commands to %s.\n", hostname); 79826049Sminshall } 79926049Sminshall else { 80026049Sminshall printf("No proxy connection.\n"); 80126049Sminshall } 80226049Sminshall pswitch(0); 80326049Sminshall } 80410294Ssam printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n", 80510294Ssam modename, typename, formname, structname); 80611353Ssam printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 80711353Ssam onoff(verbose), onoff(bell), onoff(interactive), 80811353Ssam onoff(doglob)); 80926049Sminshall printf("Store unique: %s; Receive unique: %s\n", onoff(sunique), 81026049Sminshall onoff(runique)); 81126049Sminshall printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag)); 81226049Sminshall if (ntflag) { 81326049Sminshall printf("Ntrans: (in) %s (out) %s\n", ntin,ntout); 81426049Sminshall } 81526049Sminshall else { 81626049Sminshall printf("Ntrans: off\n"); 81726049Sminshall } 81826049Sminshall if (mapflag) { 81926049Sminshall printf("Nmap: (in) %s (out) %s\n", mapin, mapout); 82026049Sminshall } 82126049Sminshall else { 82226049Sminshall printf("Nmap: off\n"); 82326049Sminshall } 82414143Ssam printf("Hash mark printing: %s; Use of PORT cmds: %s\n", 82514143Ssam onoff(hash), onoff(sendport)); 82626049Sminshall if (macnum > 0) { 82726049Sminshall printf("Macros:\n"); 82826049Sminshall for (i=0; i<macnum; i++) { 82926049Sminshall printf("\t%s\n",macros[i].mac_name); 83026049Sminshall } 83126049Sminshall } 83226049Sminshall code = 0; 83310294Ssam } 83410294Ssam 83510294Ssam /* 83610294Ssam * Set beep on cmd completed mode. 83710294Ssam */ 83810294Ssam /*VARARGS*/ 83910294Ssam setbell() 84010294Ssam { 84110294Ssam 84210294Ssam bell = !bell; 84310294Ssam printf("Bell mode %s.\n", onoff(bell)); 84426049Sminshall code = bell; 84510294Ssam } 84610294Ssam 84710294Ssam /* 84810294Ssam * Turn on packet tracing. 84910294Ssam */ 85010294Ssam /*VARARGS*/ 85110294Ssam settrace() 85210294Ssam { 85310294Ssam 85410294Ssam trace = !trace; 85510294Ssam printf("Packet tracing %s.\n", onoff(trace)); 85626049Sminshall code = trace; 85710294Ssam } 85810294Ssam 85910294Ssam /* 86011650Ssam * Toggle hash mark printing during transfers. 86111650Ssam */ 86211650Ssam /*VARARGS*/ 86311650Ssam sethash() 86411650Ssam { 86511650Ssam 86611650Ssam hash = !hash; 86711650Ssam printf("Hash mark printing %s", onoff(hash)); 86826049Sminshall code = hash; 86911650Ssam if (hash) 87037224Skarels printf(" (%d bytes/hash mark)", 1024); 87111650Ssam printf(".\n"); 87211650Ssam } 87311650Ssam 87411650Ssam /* 87510294Ssam * Turn on printing of server echo's. 87610294Ssam */ 87710294Ssam /*VARARGS*/ 87810294Ssam setverbose() 87910294Ssam { 88010294Ssam 88110294Ssam verbose = !verbose; 88210294Ssam printf("Verbose mode %s.\n", onoff(verbose)); 88326049Sminshall code = verbose; 88410294Ssam } 88510294Ssam 88610294Ssam /* 88711650Ssam * Toggle PORT cmd use before each data connection. 88811650Ssam */ 88911650Ssam /*VARARGS*/ 89011650Ssam setport() 89111650Ssam { 89211650Ssam 89311650Ssam sendport = !sendport; 89411650Ssam printf("Use of PORT cmds %s.\n", onoff(sendport)); 89526049Sminshall code = sendport; 89611650Ssam } 89711650Ssam 89811650Ssam /* 89910294Ssam * Turn on interactive prompting 90010294Ssam * during mget, mput, and mdelete. 90110294Ssam */ 90210294Ssam /*VARARGS*/ 90310294Ssam setprompt() 90410294Ssam { 90510294Ssam 90610294Ssam interactive = !interactive; 90710294Ssam printf("Interactive mode %s.\n", onoff(interactive)); 90826049Sminshall code = interactive; 90910294Ssam } 91010294Ssam 91110294Ssam /* 91211353Ssam * Toggle metacharacter interpretation 91311353Ssam * on local file names. 91411353Ssam */ 91511353Ssam /*VARARGS*/ 91611353Ssam setglob() 91711353Ssam { 91811353Ssam 91911353Ssam doglob = !doglob; 92011353Ssam printf("Globbing %s.\n", onoff(doglob)); 92126049Sminshall code = doglob; 92211353Ssam } 92311353Ssam 92411353Ssam /* 92510294Ssam * Set debugging mode on/off and/or 92610294Ssam * set level of debugging. 92710294Ssam */ 92811756Ssam /*VARARGS*/ 92910294Ssam setdebug(argc, argv) 93010294Ssam char *argv[]; 93110294Ssam { 93210294Ssam int val; 93310294Ssam 93410294Ssam if (argc > 1) { 93510294Ssam val = atoi(argv[1]); 93610294Ssam if (val < 0) { 93710294Ssam printf("%s: bad debugging value.\n", argv[1]); 93826049Sminshall code = -1; 93910294Ssam return; 94010294Ssam } 94110294Ssam } else 94210294Ssam val = !debug; 94310294Ssam debug = val; 94410294Ssam if (debug) 94510294Ssam options |= SO_DEBUG; 94610294Ssam else 94710294Ssam options &= ~SO_DEBUG; 94810294Ssam printf("Debugging %s (debug=%d).\n", onoff(debug), debug); 94926049Sminshall code = debug > 0; 95010294Ssam } 95110294Ssam 95210294Ssam /* 95310294Ssam * Set current working directory 95410294Ssam * on remote machine. 95510294Ssam */ 95610294Ssam cd(argc, argv) 95710294Ssam char *argv[]; 95810294Ssam { 95910294Ssam 96010294Ssam if (argc < 2) { 96126497Sminshall (void) strcat(line, " "); 96210294Ssam printf("(remote-directory) "); 96326497Sminshall (void) gets(&line[strlen(line)]); 96410294Ssam makeargv(); 96510294Ssam argc = margc; 96610294Ssam argv = margv; 96710294Ssam } 96810294Ssam if (argc < 2) { 96926049Sminshall printf("usage:%s remote-directory\n", argv[0]); 97026049Sminshall code = -1; 97110294Ssam return; 97210294Ssam } 97337224Skarels if (command("CWD %s", argv[1]) == ERROR && code == 500) { 97437224Skarels if (verbose) 97537224Skarels printf("CWD command not recognized, trying XCWD\n"); 97637224Skarels (void) command("XCWD %s", argv[1]); 97737224Skarels } 97810294Ssam } 97910294Ssam 98010294Ssam /* 98110294Ssam * Set current working directory 98210294Ssam * on local machine. 98310294Ssam */ 98410294Ssam lcd(argc, argv) 98510294Ssam char *argv[]; 98610294Ssam { 98711353Ssam char buf[MAXPATHLEN]; 98810294Ssam 98911353Ssam if (argc < 2) 99011353Ssam argc++, argv[1] = home; 99110294Ssam if (argc != 2) { 99226049Sminshall printf("usage:%s local-directory\n", argv[0]); 99326049Sminshall code = -1; 99410294Ssam return; 99510294Ssam } 99626049Sminshall if (!globulize(&argv[1])) { 99726049Sminshall code = -1; 99811353Ssam return; 99926049Sminshall } 100011353Ssam if (chdir(argv[1]) < 0) { 100110294Ssam perror(argv[1]); 100226049Sminshall code = -1; 100311353Ssam return; 100411353Ssam } 100511353Ssam printf("Local directory now %s\n", getwd(buf)); 100626049Sminshall code = 0; 100710294Ssam } 100810294Ssam 100910294Ssam /* 101010294Ssam * Delete a single file. 101110294Ssam */ 101210294Ssam delete(argc, argv) 101310294Ssam char *argv[]; 101410294Ssam { 101510294Ssam 101610294Ssam if (argc < 2) { 101726497Sminshall (void) strcat(line, " "); 101810294Ssam printf("(remote-file) "); 101926497Sminshall (void) gets(&line[strlen(line)]); 102010294Ssam makeargv(); 102110294Ssam argc = margc; 102210294Ssam argv = margv; 102310294Ssam } 102410294Ssam if (argc < 2) { 102526049Sminshall printf("usage:%s remote-file\n", argv[0]); 102626049Sminshall code = -1; 102710294Ssam return; 102810294Ssam } 102910294Ssam (void) command("DELE %s", argv[1]); 103010294Ssam } 103110294Ssam 103210294Ssam /* 103311650Ssam * Delete multiple files. 103411650Ssam */ 103511650Ssam mdelete(argc, argv) 103611650Ssam char *argv[]; 103711650Ssam { 103811650Ssam char *cp; 103926049Sminshall int ointer, (*oldintr)(), mabort(); 104026049Sminshall extern jmp_buf jabort; 104111650Ssam 104211650Ssam if (argc < 2) { 104326497Sminshall (void) strcat(line, " "); 104411650Ssam printf("(remote-files) "); 104526497Sminshall (void) gets(&line[strlen(line)]); 104611650Ssam makeargv(); 104711650Ssam argc = margc; 104811650Ssam argv = margv; 104911650Ssam } 105011650Ssam if (argc < 2) { 105126049Sminshall printf("usage:%s remote-files\n", argv[0]); 105226049Sminshall code = -1; 105311650Ssam return; 105411650Ssam } 105526049Sminshall mname = argv[0]; 105626049Sminshall mflag = 1; 105726049Sminshall oldintr = signal(SIGINT, mabort); 105826049Sminshall (void) setjmp(jabort); 105926497Sminshall while ((cp = remglob(argv,0)) != NULL) { 106026049Sminshall if (*cp == '\0') { 106126049Sminshall mflag = 0; 106226049Sminshall continue; 106326049Sminshall } 106426049Sminshall if (mflag && confirm(argv[0], cp)) { 106511650Ssam (void) command("DELE %s", cp); 106626049Sminshall if (!mflag && fromatty) { 106726049Sminshall ointer = interactive; 106826049Sminshall interactive = 1; 106926049Sminshall if (confirm("Continue with", "mdelete")) { 107026049Sminshall mflag++; 107126049Sminshall } 107226049Sminshall interactive = ointer; 107326049Sminshall } 107426049Sminshall } 107526049Sminshall } 107626049Sminshall (void) signal(SIGINT, oldintr); 107726049Sminshall mflag = 0; 107811650Ssam } 107911756Ssam 108011650Ssam /* 108110294Ssam * Rename a remote file. 108210294Ssam */ 108310294Ssam renamefile(argc, argv) 108410294Ssam char *argv[]; 108510294Ssam { 108610294Ssam 108710294Ssam if (argc < 2) { 108826497Sminshall (void) strcat(line, " "); 108910294Ssam printf("(from-name) "); 109026497Sminshall (void) gets(&line[strlen(line)]); 109110294Ssam makeargv(); 109210294Ssam argc = margc; 109310294Ssam argv = margv; 109410294Ssam } 109510294Ssam if (argc < 2) { 109610294Ssam usage: 109710294Ssam printf("%s from-name to-name\n", argv[0]); 109826049Sminshall code = -1; 109910294Ssam return; 110010294Ssam } 110110294Ssam if (argc < 3) { 110226497Sminshall (void) strcat(line, " "); 110310294Ssam printf("(to-name) "); 110426497Sminshall (void) gets(&line[strlen(line)]); 110510294Ssam makeargv(); 110610294Ssam argc = margc; 110710294Ssam argv = margv; 110810294Ssam } 110910294Ssam if (argc < 3) 111010294Ssam goto usage; 111110294Ssam if (command("RNFR %s", argv[1]) == CONTINUE) 111210294Ssam (void) command("RNTO %s", argv[2]); 111310294Ssam } 111410294Ssam 111510294Ssam /* 111610294Ssam * Get a directory listing 111710294Ssam * of remote files. 111810294Ssam */ 111910294Ssam ls(argc, argv) 112010294Ssam char *argv[]; 112110294Ssam { 112211756Ssam char *cmd; 112310294Ssam 112410294Ssam if (argc < 2) 112510294Ssam argc++, argv[1] = NULL; 112610294Ssam if (argc < 3) 112710294Ssam argc++, argv[2] = "-"; 112811756Ssam if (argc > 3) { 112911756Ssam printf("usage: %s remote-directory local-file\n", argv[0]); 113026049Sminshall code = -1; 113111756Ssam return; 113211756Ssam } 113336935Skarels cmd = argv[0][0] == 'n' ? "NLST" : "LIST"; 113426049Sminshall if (strcmp(argv[2], "-") && !globulize(&argv[2])) { 113526049Sminshall code = -1; 113611353Ssam return; 113726049Sminshall } 113832344Scsvsj if (strcmp(argv[2], "-") && *argv[2] != '|') 113932344Scsvsj if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) { 114032344Scsvsj code = -1; 114132344Scsvsj return; 114232344Scsvsj } 114337225Skarels recvrequest(cmd, argv[2], argv[1], "w", 0); 114410294Ssam } 114510294Ssam 114610294Ssam /* 114711756Ssam * Get a directory listing 114811756Ssam * of multiple remote files. 114911756Ssam */ 115011756Ssam mls(argc, argv) 115111756Ssam char *argv[]; 115211756Ssam { 115326049Sminshall char *cmd, mode[1], *dest; 115426049Sminshall int ointer, i, (*oldintr)(), mabort(); 115526049Sminshall extern jmp_buf jabort; 115611756Ssam 115713212Ssam if (argc < 2) { 115826497Sminshall (void) strcat(line, " "); 115913212Ssam printf("(remote-files) "); 116026497Sminshall (void) gets(&line[strlen(line)]); 116113212Ssam makeargv(); 116213212Ssam argc = margc; 116313212Ssam argv = margv; 116413212Ssam } 116513212Ssam if (argc < 3) { 116626497Sminshall (void) strcat(line, " "); 116713212Ssam printf("(local-file) "); 116826497Sminshall (void) gets(&line[strlen(line)]); 116913212Ssam makeargv(); 117013212Ssam argc = margc; 117113212Ssam argv = margv; 117213212Ssam } 117313212Ssam if (argc < 3) { 117426049Sminshall printf("usage:%s remote-files local-file\n", argv[0]); 117526049Sminshall code = -1; 117613212Ssam return; 117713212Ssam } 117813212Ssam dest = argv[argc - 1]; 117913212Ssam argv[argc - 1] = NULL; 118026049Sminshall if (strcmp(dest, "-") && *dest != '|') 118126049Sminshall if (!globulize(&dest) || !confirm("output to local-file:", dest)) { 118226049Sminshall code = -1; 118313212Ssam return; 118426049Sminshall } 118536940Skarels cmd = argv[0][1] == 'l' ? "NLST" : "LIST"; 118626049Sminshall mname = argv[0]; 118726049Sminshall mflag = 1; 118826049Sminshall oldintr = signal(SIGINT, mabort); 118926049Sminshall (void) setjmp(jabort); 119026049Sminshall for (i = 1; mflag && i < argc-1; ++i) { 119126049Sminshall *mode = (i == 1) ? 'w' : 'a'; 119237225Skarels recvrequest(cmd, dest, argv[i], mode, 0); 119326049Sminshall if (!mflag && fromatty) { 119426049Sminshall ointer = interactive; 119526049Sminshall interactive = 1; 119626049Sminshall if (confirm("Continue with", argv[0])) { 119726049Sminshall mflag ++; 119826049Sminshall } 119926049Sminshall interactive = ointer; 120026049Sminshall } 120126049Sminshall } 120226049Sminshall (void) signal(SIGINT, oldintr); 120326049Sminshall mflag = 0; 120411756Ssam } 120511756Ssam 120611756Ssam /* 120710294Ssam * Do a shell escape 120810294Ssam */ 120926497Sminshall /*ARGSUSED*/ 121010294Ssam shell(argc, argv) 121110294Ssam char *argv[]; 121210294Ssam { 121326497Sminshall int pid, (*old1)(), (*old2)(); 121426049Sminshall char shellnam[40], *shell, *namep; 121526497Sminshall union wait status; 121610294Ssam 121711756Ssam old1 = signal (SIGINT, SIG_IGN); 121811756Ssam old2 = signal (SIGQUIT, SIG_IGN); 121911756Ssam if ((pid = fork()) == 0) { 122011756Ssam for (pid = 3; pid < 20; pid++) 122126497Sminshall (void) close(pid); 122226497Sminshall (void) signal(SIGINT, SIG_DFL); 122326497Sminshall (void) signal(SIGQUIT, SIG_DFL); 122425908Smckusick shell = getenv("SHELL"); 122525908Smckusick if (shell == NULL) 1226*37458Skarels shell = _PATH_BSHELL; 122725908Smckusick namep = rindex(shell,'/'); 122825908Smckusick if (namep == NULL) 122925908Smckusick namep = shell; 123026497Sminshall (void) strcpy(shellnam,"-"); 123126497Sminshall (void) strcat(shellnam, ++namep); 123226049Sminshall if (strcmp(namep, "sh") != 0) 123326049Sminshall shellnam[0] = '+'; 123426049Sminshall if (debug) { 123526049Sminshall printf ("%s\n", shell); 123626497Sminshall (void) fflush (stdout); 123711756Ssam } 123826049Sminshall if (argc > 1) { 123926049Sminshall execl(shell,shellnam,"-c",altarg,(char *)0); 124026049Sminshall } 124126049Sminshall else { 124226049Sminshall execl(shell,shellnam,(char *)0); 124326049Sminshall } 124425908Smckusick perror(shell); 124526049Sminshall code = -1; 124611756Ssam exit(1); 124726049Sminshall } 124811756Ssam if (pid > 0) 124911756Ssam while (wait(&status) != pid) 125011756Ssam ; 125126497Sminshall (void) signal(SIGINT, old1); 125226497Sminshall (void) signal(SIGQUIT, old2); 125326049Sminshall if (pid == -1) { 125411756Ssam perror("Try again later"); 125526049Sminshall code = -1; 125626049Sminshall } 125726049Sminshall else { 125826049Sminshall code = 0; 125926049Sminshall } 126011756Ssam return (0); 126110294Ssam } 126210294Ssam 126310294Ssam /* 126410294Ssam * Send new user information (re-login) 126510294Ssam */ 126610294Ssam user(argc, argv) 126710294Ssam int argc; 126810294Ssam char **argv; 126910294Ssam { 127035658Sbostic char acct[80], *getpass(); 127126049Sminshall int n, aflag = 0; 127210294Ssam 127310294Ssam if (argc < 2) { 127426497Sminshall (void) strcat(line, " "); 127510294Ssam printf("(username) "); 127626497Sminshall (void) gets(&line[strlen(line)]); 127710294Ssam makeargv(); 127810294Ssam argc = margc; 127910294Ssam argv = margv; 128010294Ssam } 128110294Ssam if (argc > 4) { 128210294Ssam printf("usage: %s username [password] [account]\n", argv[0]); 128326049Sminshall code = -1; 128411756Ssam return (0); 128510294Ssam } 128610294Ssam n = command("USER %s", argv[1]); 128710294Ssam if (n == CONTINUE) { 128810294Ssam if (argc < 3 ) 128935658Sbostic argv[2] = getpass("Password: "), argc++; 129010294Ssam n = command("PASS %s", argv[2]); 129110294Ssam } 129210294Ssam if (n == CONTINUE) { 129310294Ssam if (argc < 4) { 129410294Ssam printf("Account: "); (void) fflush(stdout); 129510294Ssam (void) fgets(acct, sizeof(acct) - 1, stdin); 129610294Ssam acct[strlen(acct) - 1] = '\0'; 129710294Ssam argv[3] = acct; argc++; 129810294Ssam } 129926049Sminshall n = command("ACCT %s", argv[3]); 130026049Sminshall aflag++; 130110294Ssam } 130210294Ssam if (n != COMPLETE) { 130326497Sminshall fprintf(stdout, "Login failed.\n"); 130410294Ssam return (0); 130510294Ssam } 130626049Sminshall if (!aflag && argc == 4) { 130726049Sminshall (void) command("ACCT %s", argv[3]); 130826049Sminshall } 130910294Ssam return (1); 131010294Ssam } 131110294Ssam 131210294Ssam /* 131310294Ssam * Print working directory. 131410294Ssam */ 131510294Ssam /*VARARGS*/ 131610294Ssam pwd() 131710294Ssam { 131837224Skarels int oldverbose = verbose; 131911756Ssam 132037224Skarels /* 132137224Skarels * If we aren't verbose, this doesn't do anything! 132237224Skarels */ 132337224Skarels verbose = 1; 132437224Skarels if (command("PWD") == ERROR && code == 500) { 132537224Skarels printf("PWD command not recognized, trying XPWD\n"); 132637224Skarels (void) command("XPWD"); 132737224Skarels } 132837224Skarels verbose = oldverbose; 132910294Ssam } 133010294Ssam 133110294Ssam /* 133210294Ssam * Make a directory. 133310294Ssam */ 133410294Ssam makedir(argc, argv) 133510294Ssam char *argv[]; 133610294Ssam { 133710294Ssam 133810294Ssam if (argc < 2) { 133926497Sminshall (void) strcat(line, " "); 134010294Ssam printf("(directory-name) "); 134126497Sminshall (void) gets(&line[strlen(line)]); 134210294Ssam makeargv(); 134310294Ssam argc = margc; 134410294Ssam argv = margv; 134510294Ssam } 134610294Ssam if (argc < 2) { 134726049Sminshall printf("usage: %s directory-name\n", argv[0]); 134826049Sminshall code = -1; 134910294Ssam return; 135010294Ssam } 135137224Skarels if (command("MKD %s", argv[1]) == ERROR && code == 500) { 135237224Skarels if (verbose) 135337224Skarels printf("MKD command not recognized, trying XMKD\n"); 135437224Skarels (void) command("XMKD %s", argv[1]); 135537224Skarels } 135610294Ssam } 135710294Ssam 135810294Ssam /* 135910294Ssam * Remove a directory. 136010294Ssam */ 136110294Ssam removedir(argc, argv) 136210294Ssam char *argv[]; 136310294Ssam { 136410294Ssam 136510294Ssam if (argc < 2) { 136626497Sminshall (void) strcat(line, " "); 136710294Ssam printf("(directory-name) "); 136826497Sminshall (void) gets(&line[strlen(line)]); 136910294Ssam makeargv(); 137010294Ssam argc = margc; 137110294Ssam argv = margv; 137210294Ssam } 137310294Ssam if (argc < 2) { 137426049Sminshall printf("usage: %s directory-name\n", argv[0]); 137526049Sminshall code = -1; 137610294Ssam return; 137710294Ssam } 137837224Skarels if (command("RMD %s", argv[1]) == ERROR && code == 500) { 137937224Skarels if (verbose) 138037224Skarels printf("RMD command not recognized, trying XRMD\n"); 138137224Skarels (void) command("XRMD %s", argv[1]); 138237224Skarels } 138310294Ssam } 138410294Ssam 138510294Ssam /* 138610294Ssam * Send a line, verbatim, to the remote machine. 138710294Ssam */ 138810294Ssam quote(argc, argv) 138910294Ssam char *argv[]; 139010294Ssam { 139110294Ssam int i; 139210294Ssam char buf[BUFSIZ]; 139310294Ssam 139410294Ssam if (argc < 2) { 139526497Sminshall (void) strcat(line, " "); 139610294Ssam printf("(command line to send) "); 139726497Sminshall (void) gets(&line[strlen(line)]); 139810294Ssam makeargv(); 139910294Ssam argc = margc; 140010294Ssam argv = margv; 140110294Ssam } 140210294Ssam if (argc < 2) { 140310294Ssam printf("usage: %s line-to-send\n", argv[0]); 140426049Sminshall code = -1; 140510294Ssam return; 140610294Ssam } 140726497Sminshall (void) strcpy(buf, argv[1]); 140810294Ssam for (i = 2; i < argc; i++) { 140926497Sminshall (void) strcat(buf, " "); 141026497Sminshall (void) strcat(buf, argv[i]); 141110294Ssam } 141226049Sminshall if (command(buf) == PRELIM) { 141326049Sminshall while (getreply(0) == PRELIM); 141426049Sminshall } 141510294Ssam } 141610294Ssam 141710294Ssam /* 141837224Skarels * Send a SITE command to the remote machine. The line 141937224Skarels * is sent almost verbatim to the remote machine, the 142037224Skarels * first argument is changed to SITE. 142137224Skarels */ 142237224Skarels 142337224Skarels site(argc, argv) 142437224Skarels char *argv[]; 142537224Skarels { 142637224Skarels int i; 142737224Skarels char buf[BUFSIZ]; 142837224Skarels 142937224Skarels if (argc < 2) { 143037224Skarels (void) strcat(line, " "); 143137224Skarels printf("(arguments to SITE command) "); 143237224Skarels (void) gets(&line[strlen(line)]); 143337224Skarels makeargv(); 143437224Skarels argc = margc; 143537224Skarels argv = margv; 143637224Skarels } 143737224Skarels if (argc < 2) { 143837224Skarels printf("usage: %s line-to-send\n", argv[0]); 143937224Skarels code = -1; 144037224Skarels return; 144137224Skarels } 144237224Skarels (void) strcpy(buf, "SITE "); 144337224Skarels (void) strcat(buf, argv[1]); 144437224Skarels for (i = 2; i < argc; i++) { 144537224Skarels (void) strcat(buf, " "); 144637224Skarels (void) strcat(buf, argv[i]); 144737224Skarels } 144837224Skarels if (command(buf) == PRELIM) { 144937224Skarels while (getreply(0) == PRELIM); 145037224Skarels } 145137224Skarels } 145237224Skarels 145337224Skarels do_chmod(argc, argv) 145437224Skarels char *argv[]; 145537224Skarels { 145637224Skarels if (argc == 2) { 145737224Skarels printf("usage: %s mode file-name\n", argv[0]); 145837224Skarels code = -1; 145937224Skarels return; 146037224Skarels } 146137224Skarels if (argc < 3) { 146237224Skarels (void) strcat(line, " "); 146337224Skarels printf("(mode and file-name) "); 146437224Skarels (void) gets(&line[strlen(line)]); 146537224Skarels makeargv(); 146637224Skarels argc = margc; 146737224Skarels argv = margv; 146837224Skarels } 146937224Skarels if (argc != 3) { 147037224Skarels printf("usage: %s mode file-name\n", argv[0]); 147137224Skarels code = -1; 147237224Skarels return; 147337224Skarels } 147437224Skarels (void)command("SITE CHMOD %s %s", argv[1], argv[2]); 147537224Skarels } 147637224Skarels 147737224Skarels do_umask(argc, argv) 147837224Skarels char *argv[]; 147937224Skarels { 148037224Skarels int oldverbose = verbose; 148137224Skarels 148237224Skarels verbose = 1; 148337224Skarels (void) command(argc == 1 ? "SITE UMASK" : "SITE UMASK %s", argv[1]); 148437224Skarels verbose = oldverbose; 148537224Skarels } 148637224Skarels 148737224Skarels idle(argc, argv) 148837224Skarels char *argv[]; 148937224Skarels { 149037224Skarels int oldverbose = verbose; 149137224Skarels 149237224Skarels verbose = 1; 149337224Skarels (void) command(argc == 1 ? "SITE IDLE" : "SITE IDLE %s", argv[1]); 149437224Skarels verbose = oldverbose; 149537224Skarels } 149637224Skarels 149737224Skarels /* 149810294Ssam * Ask the other side for help. 149910294Ssam */ 150010294Ssam rmthelp(argc, argv) 150110294Ssam char *argv[]; 150210294Ssam { 150310294Ssam int oldverbose = verbose; 150410294Ssam 150510294Ssam verbose = 1; 150610294Ssam (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]); 150710294Ssam verbose = oldverbose; 150810294Ssam } 150910294Ssam 151010294Ssam /* 151110294Ssam * Terminate session and exit. 151210294Ssam */ 151310294Ssam /*VARARGS*/ 151410294Ssam quit() 151510294Ssam { 151610294Ssam 151718286Sralph if (connected) 151818286Sralph disconnect(); 151926049Sminshall pswitch(1); 152026049Sminshall if (connected) { 152126049Sminshall disconnect(); 152226049Sminshall } 152310294Ssam exit(0); 152410294Ssam } 152510294Ssam 152610294Ssam /* 152710294Ssam * Terminate session, but don't exit. 152810294Ssam */ 152910294Ssam disconnect() 153010294Ssam { 153110294Ssam extern FILE *cout; 153210294Ssam extern int data; 153310294Ssam 153410294Ssam if (!connected) 153510294Ssam return; 153610294Ssam (void) command("QUIT"); 153726049Sminshall if (cout) { 153826049Sminshall (void) fclose(cout); 153926049Sminshall } 154010294Ssam cout = NULL; 154110294Ssam connected = 0; 154210294Ssam data = -1; 154326049Sminshall if (!proxy) { 154426049Sminshall macnum = 0; 154526049Sminshall } 154610294Ssam } 154711353Ssam 154811650Ssam confirm(cmd, file) 154911353Ssam char *cmd, *file; 155011353Ssam { 155111353Ssam char line[BUFSIZ]; 155211353Ssam 155311353Ssam if (!interactive) 155411650Ssam return (1); 155511353Ssam printf("%s %s? ", cmd, file); 155626497Sminshall (void) fflush(stdout); 155726497Sminshall (void) gets(line); 155811650Ssam return (*line != 'n' && *line != 'N'); 155911353Ssam } 156011353Ssam 156111353Ssam fatal(msg) 156211353Ssam char *msg; 156311353Ssam { 156411353Ssam 156526497Sminshall fprintf(stderr, "ftp: %s\n", msg); 156611353Ssam exit(1); 156711353Ssam } 156811353Ssam 156911353Ssam /* 157011353Ssam * Glob a local file name specification with 157111353Ssam * the expectation of a single return value. 157211353Ssam * Can't control multiple values being expanded 157311353Ssam * from the expression, we return only the first. 157411353Ssam */ 157511353Ssam globulize(cpp) 157611353Ssam char **cpp; 157711353Ssam { 157811353Ssam char **globbed; 157911353Ssam 158011353Ssam if (!doglob) 158111353Ssam return (1); 158211353Ssam globbed = glob(*cpp); 158311353Ssam if (globerr != NULL) { 158411353Ssam printf("%s: %s\n", *cpp, globerr); 158536421Sbostic if (globbed) { 158611353Ssam blkfree(globbed); 158736421Sbostic free(globbed); 158836421Sbostic } 158911353Ssam return (0); 159011353Ssam } 159111353Ssam if (globbed) { 159211353Ssam *cpp = *globbed++; 159311353Ssam /* don't waste too much memory */ 159436421Sbostic if (*globbed) { 159511353Ssam blkfree(globbed); 159636421Sbostic free(globbed); 159736421Sbostic } 159811353Ssam } 159911353Ssam return (1); 160011353Ssam } 160126049Sminshall 160226049Sminshall account(argc,argv) 160326049Sminshall int argc; 160426049Sminshall char **argv; 160526049Sminshall { 160635658Sbostic char acct[50], *getpass(), *ap; 160726049Sminshall 160826049Sminshall if (argc > 1) { 160926049Sminshall ++argv; 161026049Sminshall --argc; 161126049Sminshall (void) strncpy(acct,*argv,49); 161236268Sbostic acct[49] = '\0'; 161326049Sminshall while (argc > 1) { 161426049Sminshall --argc; 161526049Sminshall ++argv; 161626049Sminshall (void) strncat(acct,*argv, 49-strlen(acct)); 161726049Sminshall } 161826049Sminshall ap = acct; 161926049Sminshall } 162026049Sminshall else { 162135658Sbostic ap = getpass("Account:"); 162226049Sminshall } 162326049Sminshall (void) command("ACCT %s", ap); 162426049Sminshall } 162526049Sminshall 162626049Sminshall jmp_buf abortprox; 162726049Sminshall 162826049Sminshall proxabort() 162926049Sminshall { 163026049Sminshall extern int proxy; 163126049Sminshall 163226049Sminshall if (!proxy) { 163326049Sminshall pswitch(1); 163426049Sminshall } 163526049Sminshall if (connected) { 163626049Sminshall proxflag = 1; 163726049Sminshall } 163826049Sminshall else { 163926049Sminshall proxflag = 0; 164026049Sminshall } 164126049Sminshall pswitch(0); 164226049Sminshall longjmp(abortprox,1); 164326049Sminshall } 164426049Sminshall 164526049Sminshall doproxy(argc,argv) 164626049Sminshall int argc; 164726049Sminshall char *argv[]; 164826049Sminshall { 164926049Sminshall int (*oldintr)(), proxabort(); 165026049Sminshall register struct cmd *c; 165126049Sminshall struct cmd *getcmd(); 165226049Sminshall extern struct cmd cmdtab[]; 165326049Sminshall extern jmp_buf abortprox; 165426049Sminshall 165526049Sminshall if (argc < 2) { 165626497Sminshall (void) strcat(line, " "); 165726049Sminshall printf("(command) "); 165826497Sminshall (void) gets(&line[strlen(line)]); 165926049Sminshall makeargv(); 166026049Sminshall argc = margc; 166126049Sminshall argv = margv; 166226049Sminshall } 166326049Sminshall if (argc < 2) { 166426049Sminshall printf("usage:%s command\n", argv[0]); 166526049Sminshall code = -1; 166626049Sminshall return; 166726049Sminshall } 166826049Sminshall c = getcmd(argv[1]); 166926049Sminshall if (c == (struct cmd *) -1) { 167026049Sminshall printf("?Ambiguous command\n"); 167126497Sminshall (void) fflush(stdout); 167226049Sminshall code = -1; 167326049Sminshall return; 167426049Sminshall } 167526049Sminshall if (c == 0) { 167626049Sminshall printf("?Invalid command\n"); 167726497Sminshall (void) fflush(stdout); 167826049Sminshall code = -1; 167926049Sminshall return; 168026049Sminshall } 168126049Sminshall if (!c->c_proxy) { 168226049Sminshall printf("?Invalid proxy command\n"); 168326497Sminshall (void) fflush(stdout); 168426049Sminshall code = -1; 168526049Sminshall return; 168626049Sminshall } 168726049Sminshall if (setjmp(abortprox)) { 168826049Sminshall code = -1; 168926049Sminshall return; 169026049Sminshall } 169126049Sminshall oldintr = signal(SIGINT, proxabort); 169226049Sminshall pswitch(1); 169326049Sminshall if (c->c_conn && !connected) { 169426049Sminshall printf("Not connected\n"); 169526497Sminshall (void) fflush(stdout); 169626049Sminshall pswitch(0); 169726049Sminshall (void) signal(SIGINT, oldintr); 169826049Sminshall code = -1; 169926049Sminshall return; 170026049Sminshall } 170126049Sminshall (*c->c_handler)(argc-1, argv+1); 170226049Sminshall if (connected) { 170326049Sminshall proxflag = 1; 170426049Sminshall } 170526049Sminshall else { 170626049Sminshall proxflag = 0; 170726049Sminshall } 170826049Sminshall pswitch(0); 170926049Sminshall (void) signal(SIGINT, oldintr); 171026049Sminshall } 171126049Sminshall 171226049Sminshall setcase() 171326049Sminshall { 171426049Sminshall mcase = !mcase; 171526049Sminshall printf("Case mapping %s.\n", onoff(mcase)); 171626049Sminshall code = mcase; 171726049Sminshall } 171826049Sminshall 171926049Sminshall setcr() 172026049Sminshall { 172126049Sminshall crflag = !crflag; 172226049Sminshall printf("Carriage Return stripping %s.\n", onoff(crflag)); 172326049Sminshall code = crflag; 172426049Sminshall } 172526049Sminshall 172626049Sminshall setntrans(argc,argv) 172726049Sminshall int argc; 172826049Sminshall char *argv[]; 172926049Sminshall { 173026049Sminshall if (argc == 1) { 173126049Sminshall ntflag = 0; 173226049Sminshall printf("Ntrans off.\n"); 173326049Sminshall code = ntflag; 173426049Sminshall return; 173526049Sminshall } 173626049Sminshall ntflag++; 173726049Sminshall code = ntflag; 173826049Sminshall (void) strncpy(ntin, argv[1], 16); 173926049Sminshall ntin[16] = '\0'; 174026049Sminshall if (argc == 2) { 174126049Sminshall ntout[0] = '\0'; 174226049Sminshall return; 174326049Sminshall } 174426049Sminshall (void) strncpy(ntout, argv[2], 16); 174526049Sminshall ntout[16] = '\0'; 174626049Sminshall } 174726049Sminshall 174826049Sminshall char * 174926049Sminshall dotrans(name) 175026049Sminshall char *name; 175126049Sminshall { 175226049Sminshall static char new[MAXPATHLEN]; 175326049Sminshall char *cp1, *cp2 = new; 175426049Sminshall register int i, ostop, found; 175526049Sminshall 175626049Sminshall for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++); 175726049Sminshall for (cp1 = name; *cp1; cp1++) { 175826049Sminshall found = 0; 175926049Sminshall for (i = 0; *(ntin + i) && i < 16; i++) { 176026049Sminshall if (*cp1 == *(ntin + i)) { 176126049Sminshall found++; 176226049Sminshall if (i < ostop) { 176326049Sminshall *cp2++ = *(ntout + i); 176426049Sminshall } 176526049Sminshall break; 176626049Sminshall } 176726049Sminshall } 176826049Sminshall if (!found) { 176926049Sminshall *cp2++ = *cp1; 177026049Sminshall } 177126049Sminshall } 177226049Sminshall *cp2 = '\0'; 177326049Sminshall return(new); 177426049Sminshall } 177526049Sminshall 177626049Sminshall setnmap(argc, argv) 177726049Sminshall int argc; 177826049Sminshall char *argv[]; 177926049Sminshall { 178026049Sminshall char *cp; 178126049Sminshall 178226049Sminshall if (argc == 1) { 178326049Sminshall mapflag = 0; 178426049Sminshall printf("Nmap off.\n"); 178526049Sminshall code = mapflag; 178626049Sminshall return; 178726049Sminshall } 178826049Sminshall if (argc < 3) { 178926497Sminshall (void) strcat(line, " "); 179026049Sminshall printf("(mapout) "); 179126497Sminshall (void) gets(&line[strlen(line)]); 179226049Sminshall makeargv(); 179326049Sminshall argc = margc; 179426049Sminshall argv = margv; 179526049Sminshall } 179626049Sminshall if (argc < 3) { 179726049Sminshall printf("Usage: %s [mapin mapout]\n",argv[0]); 179826049Sminshall code = -1; 179926049Sminshall return; 180026049Sminshall } 180126049Sminshall mapflag = 1; 180226049Sminshall code = 1; 180326049Sminshall cp = index(altarg, ' '); 180426049Sminshall if (proxy) { 180526049Sminshall while(*++cp == ' '); 180626049Sminshall altarg = cp; 180726049Sminshall cp = index(altarg, ' '); 180826049Sminshall } 180926049Sminshall *cp = '\0'; 181026049Sminshall (void) strncpy(mapin, altarg, MAXPATHLEN - 1); 181126049Sminshall while (*++cp == ' '); 181226049Sminshall (void) strncpy(mapout, cp, MAXPATHLEN - 1); 181326049Sminshall } 181426049Sminshall 181526049Sminshall char * 181626049Sminshall domap(name) 181726049Sminshall char *name; 181826049Sminshall { 181926049Sminshall static char new[MAXPATHLEN]; 182026049Sminshall register char *cp1 = name, *cp2 = mapin; 182126049Sminshall char *tp[9], *te[9]; 182236689Scsvsj int i, toks[9], toknum = 0, match = 1; 182326049Sminshall 182426049Sminshall for (i=0; i < 9; ++i) { 182526049Sminshall toks[i] = 0; 182626049Sminshall } 182726049Sminshall while (match && *cp1 && *cp2) { 182826049Sminshall switch (*cp2) { 182926049Sminshall case '\\': 183026049Sminshall if (*++cp2 != *cp1) { 183126049Sminshall match = 0; 183226049Sminshall } 183326049Sminshall break; 183426049Sminshall case '$': 183526049Sminshall if (*(cp2+1) >= '1' && (*cp2+1) <= '9') { 183626049Sminshall if (*cp1 != *(++cp2+1)) { 183726049Sminshall toks[toknum = *cp2 - '1']++; 183826049Sminshall tp[toknum] = cp1; 183926049Sminshall while (*++cp1 && *(cp2+1) 184026049Sminshall != *cp1); 184126049Sminshall te[toknum] = cp1; 184226049Sminshall } 184326049Sminshall cp2++; 184426049Sminshall break; 184526049Sminshall } 184636935Skarels /* FALLTHROUGH */ 184726049Sminshall default: 184826049Sminshall if (*cp2 != *cp1) { 184926049Sminshall match = 0; 185026049Sminshall } 185126049Sminshall break; 185226049Sminshall } 185336689Scsvsj if (match && *cp1) { 185426049Sminshall cp1++; 185526049Sminshall } 185636689Scsvsj if (match && *cp2) { 185726049Sminshall cp2++; 185826049Sminshall } 185926049Sminshall } 186036689Scsvsj if (!match && *cp1) /* last token mismatch */ 186136689Scsvsj { 186236689Scsvsj toks[toknum] = 0; 186336689Scsvsj } 186426049Sminshall cp1 = new; 186526049Sminshall *cp1 = '\0'; 186626049Sminshall cp2 = mapout; 186726049Sminshall while (*cp2) { 186826049Sminshall match = 0; 186926049Sminshall switch (*cp2) { 187026049Sminshall case '\\': 187126049Sminshall if (*(cp2 + 1)) { 187226049Sminshall *cp1++ = *++cp2; 187326049Sminshall } 187426049Sminshall break; 187526049Sminshall case '[': 187626049Sminshall LOOP: 187726049Sminshall if (*++cp2 == '$' && isdigit(*(cp2+1))) { 187826049Sminshall if (*++cp2 == '0') { 187926049Sminshall char *cp3 = name; 188026049Sminshall 188126049Sminshall while (*cp3) { 188226049Sminshall *cp1++ = *cp3++; 188326049Sminshall } 188426049Sminshall match = 1; 188526049Sminshall } 188626049Sminshall else if (toks[toknum = *cp2 - '1']) { 188726049Sminshall char *cp3 = tp[toknum]; 188826049Sminshall 188926049Sminshall while (cp3 != te[toknum]) { 189026049Sminshall *cp1++ = *cp3++; 189126049Sminshall } 189226049Sminshall match = 1; 189326049Sminshall } 189426049Sminshall } 189526049Sminshall else { 189626049Sminshall while (*cp2 && *cp2 != ',' && 189726049Sminshall *cp2 != ']') { 189826049Sminshall if (*cp2 == '\\') { 189926049Sminshall cp2++; 190026049Sminshall } 190126049Sminshall else if (*cp2 == '$' && 190226049Sminshall isdigit(*(cp2+1))) { 190326049Sminshall if (*++cp2 == '0') { 190426049Sminshall char *cp3 = name; 190526049Sminshall 190626049Sminshall while (*cp3) { 190726049Sminshall *cp1++ = *cp3++; 190826049Sminshall } 190926049Sminshall } 191026049Sminshall else if (toks[toknum = 191126049Sminshall *cp2 - '1']) { 191226049Sminshall char *cp3=tp[toknum]; 191326049Sminshall 191426049Sminshall while (cp3 != 191526049Sminshall te[toknum]) { 191626049Sminshall *cp1++ = *cp3++; 191726049Sminshall } 191826049Sminshall } 191926049Sminshall } 192026049Sminshall else if (*cp2) { 192126049Sminshall *cp1++ = *cp2++; 192226049Sminshall } 192326049Sminshall } 192426049Sminshall if (!*cp2) { 192526049Sminshall printf("nmap: unbalanced brackets\n"); 192626049Sminshall return(name); 192726049Sminshall } 192826049Sminshall match = 1; 192926049Sminshall cp2--; 193026049Sminshall } 193126049Sminshall if (match) { 193226049Sminshall while (*++cp2 && *cp2 != ']') { 193326049Sminshall if (*cp2 == '\\' && *(cp2 + 1)) { 193426049Sminshall cp2++; 193526049Sminshall } 193626049Sminshall } 193726049Sminshall if (!*cp2) { 193826049Sminshall printf("nmap: unbalanced brackets\n"); 193926049Sminshall return(name); 194026049Sminshall } 194126049Sminshall break; 194226049Sminshall } 194326049Sminshall switch (*++cp2) { 194426049Sminshall case ',': 194526049Sminshall goto LOOP; 194626049Sminshall case ']': 194726049Sminshall break; 194826049Sminshall default: 194926049Sminshall cp2--; 195026049Sminshall goto LOOP; 195126049Sminshall } 195226049Sminshall break; 195326049Sminshall case '$': 195426049Sminshall if (isdigit(*(cp2 + 1))) { 195526049Sminshall if (*++cp2 == '0') { 195626049Sminshall char *cp3 = name; 195726049Sminshall 195826049Sminshall while (*cp3) { 195926049Sminshall *cp1++ = *cp3++; 196026049Sminshall } 196126049Sminshall } 196226049Sminshall else if (toks[toknum = *cp2 - '1']) { 196326049Sminshall char *cp3 = tp[toknum]; 196426049Sminshall 196526049Sminshall while (cp3 != te[toknum]) { 196626049Sminshall *cp1++ = *cp3++; 196726049Sminshall } 196826049Sminshall } 196926049Sminshall break; 197026049Sminshall } 197126049Sminshall /* intentional drop through */ 197226049Sminshall default: 197326049Sminshall *cp1++ = *cp2; 197426049Sminshall break; 197526049Sminshall } 197626049Sminshall cp2++; 197726049Sminshall } 197826049Sminshall *cp1 = '\0'; 197926049Sminshall if (!*new) { 198026049Sminshall return(name); 198126049Sminshall } 198226049Sminshall return(new); 198326049Sminshall } 198426049Sminshall 198526049Sminshall setsunique() 198626049Sminshall { 198726049Sminshall sunique = !sunique; 198826049Sminshall printf("Store unique %s.\n", onoff(sunique)); 198926049Sminshall code = sunique; 199026049Sminshall } 199126049Sminshall 199226049Sminshall setrunique() 199326049Sminshall { 199426049Sminshall runique = !runique; 199526049Sminshall printf("Receive unique %s.\n", onoff(runique)); 199626049Sminshall code = runique; 199726049Sminshall } 199826049Sminshall 199926049Sminshall /* change directory to perent directory */ 200026049Sminshall cdup() 200126049Sminshall { 200237224Skarels if (command("CDUP") == ERROR && code == 500) { 200337224Skarels if (verbose) 200437224Skarels printf("CDUP command not recognized, trying XCUP\n"); 200537224Skarels (void) command("XCUP"); 200637224Skarels } 200726049Sminshall } 200826049Sminshall 200937224Skarels /* restart transfer at specific point */ 201037224Skarels restart(argc, argv) 201137224Skarels int argc; 201237224Skarels char *argv[]; 201337224Skarels { 201437224Skarels extern long atol(); 201537224Skarels if (argc != 2) 201637224Skarels printf("restart: offset not specified\n"); 201737224Skarels else { 201837224Skarels restart_point = atol(argv[1]); 201937224Skarels printf("restarting at %ld. %s\n", restart_point, 202037224Skarels "execute get, put or append to initiate transfer"); 202137224Skarels } 202237224Skarels } 202336935Skarels 202436935Skarels /* show remote system type */ 202536935Skarels syst() 202636935Skarels { 202736935Skarels (void) command("SYST"); 202836935Skarels } 202936935Skarels 203026049Sminshall macdef(argc, argv) 203126049Sminshall int argc; 203226049Sminshall char *argv[]; 203326049Sminshall { 203426049Sminshall char *tmp; 203526049Sminshall int c; 203626049Sminshall 203726049Sminshall if (macnum == 16) { 203826049Sminshall printf("Limit of 16 macros have already been defined\n"); 203926049Sminshall code = -1; 204026049Sminshall return; 204126049Sminshall } 204226049Sminshall if (argc < 2) { 204326497Sminshall (void) strcat(line, " "); 204426049Sminshall printf("(macro name) "); 204526497Sminshall (void) gets(&line[strlen(line)]); 204626049Sminshall makeargv(); 204726049Sminshall argc = margc; 204826049Sminshall argv = margv; 204926049Sminshall } 205026049Sminshall if (argc != 2) { 205126049Sminshall printf("Usage: %s macro_name\n",argv[0]); 205226049Sminshall code = -1; 205326049Sminshall return; 205426049Sminshall } 205526049Sminshall if (interactive) { 205626049Sminshall printf("Enter macro line by line, terminating it with a null line\n"); 205726049Sminshall } 205826497Sminshall (void) strncpy(macros[macnum].mac_name, argv[1], 8); 205926049Sminshall if (macnum == 0) { 206026049Sminshall macros[macnum].mac_start = macbuf; 206126049Sminshall } 206226049Sminshall else { 206326049Sminshall macros[macnum].mac_start = macros[macnum - 1].mac_end + 1; 206426049Sminshall } 206526049Sminshall tmp = macros[macnum].mac_start; 206626049Sminshall while (tmp != macbuf+4096) { 206726049Sminshall if ((c = getchar()) == EOF) { 206826049Sminshall printf("macdef:end of file encountered\n"); 206926049Sminshall code = -1; 207026049Sminshall return; 207126049Sminshall } 207226049Sminshall if ((*tmp = c) == '\n') { 207326049Sminshall if (tmp == macros[macnum].mac_start) { 207426049Sminshall macros[macnum++].mac_end = tmp; 207526049Sminshall code = 0; 207626049Sminshall return; 207726049Sminshall } 207826049Sminshall if (*(tmp-1) == '\0') { 207926049Sminshall macros[macnum++].mac_end = tmp - 1; 208026049Sminshall code = 0; 208126049Sminshall return; 208226049Sminshall } 208326049Sminshall *tmp = '\0'; 208426049Sminshall } 208526049Sminshall tmp++; 208626049Sminshall } 208726049Sminshall while (1) { 208836935Skarels while ((c = getchar()) != '\n' && c != EOF) 208936935Skarels /* LOOP */; 209026049Sminshall if (c == EOF || getchar() == '\n') { 209126049Sminshall printf("Macro not defined - 4k buffer exceeded\n"); 209226049Sminshall code = -1; 209326049Sminshall return; 209426049Sminshall } 209526049Sminshall } 209626049Sminshall } 209736935Skarels 209836935Skarels /* 209936935Skarels * get size of file on remote machine 210036935Skarels */ 210136935Skarels sizecmd(argc, argv) 210236935Skarels char *argv[]; 210336935Skarels { 210436935Skarels 210536935Skarels if (argc < 2) { 210636935Skarels (void) strcat(line, " "); 210736935Skarels printf("(filename) "); 210836935Skarels (void) gets(&line[strlen(line)]); 210936935Skarels makeargv(); 211036935Skarels argc = margc; 211136935Skarels argv = margv; 211236935Skarels } 211336935Skarels if (argc < 2) { 211436935Skarels printf("usage:%s filename\n", argv[0]); 211536935Skarels code = -1; 211636935Skarels return; 211736935Skarels } 211836935Skarels (void) command("SIZE %s", argv[1]); 211936935Skarels } 212036935Skarels 212136935Skarels /* 212236935Skarels * get last modification time of file on remote machine 212336935Skarels */ 212436935Skarels modtime(argc, argv) 212536935Skarels char *argv[]; 212636935Skarels { 212736935Skarels int overbose; 212836935Skarels 212936935Skarels if (argc < 2) { 213036935Skarels (void) strcat(line, " "); 213136935Skarels printf("(filename) "); 213236935Skarels (void) gets(&line[strlen(line)]); 213336935Skarels makeargv(); 213436935Skarels argc = margc; 213536935Skarels argv = margv; 213636935Skarels } 213736935Skarels if (argc < 2) { 213836935Skarels printf("usage:%s filename\n", argv[0]); 213936935Skarels code = -1; 214036935Skarels return; 214136935Skarels } 214236940Skarels overbose = verbose; 214336940Skarels if (debug == 0) 214436940Skarels verbose = -1; 214536935Skarels if (command("MDTM %s", argv[1]) == COMPLETE) { 214636935Skarels int yy, mo, day, hour, min, sec; 214736935Skarels sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo, 214836935Skarels &day, &hour, &min, &sec); 214936935Skarels /* might want to print this in local time */ 215036935Skarels printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1], 215136935Skarels mo, day, yy, hour, min, sec); 215236935Skarels } else 215336935Skarels fputs(reply_string, stdout); 215436935Skarels verbose = overbose; 215536935Skarels } 215636935Skarels 215736935Skarels /* 215837224Skarels * show status on reomte machine 215936935Skarels */ 216036935Skarels rmtstatus(argc, argv) 216136935Skarels char *argv[]; 216236935Skarels { 216336935Skarels (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]); 216436935Skarels } 216537224Skarels 216637224Skarels /* 216737224Skarels * get file if modtime is more recent than current file 216837224Skarels */ 216937224Skarels newer(argc, argv) 217037224Skarels char *argv[]; 217137224Skarels { 217237224Skarels if (getit(argc, argv, -1, "w")) 217337224Skarels printf("Local file \"%s\" is newer than remote file \"%s\"\n", 217437224Skarels argv[1], argv[2]); 217537224Skarels } 2176