+
+account(argc,argv)
+ int argc;
+ char **argv;
+{
+ char acct[50], *getpass(), *ap;
+
+ if (argc > 1) {
+ ++argv;
+ --argc;
+ (void) strncpy(acct,*argv,49);
+ acct[49] = '\0';
+ while (argc > 1) {
+ --argc;
+ ++argv;
+ (void) strncat(acct,*argv, 49-strlen(acct));
+ }
+ ap = acct;
+ }
+ else {
+ ap = getpass("Account:");
+ }
+ (void) command("ACCT %s", ap);
+}
+
+jmp_buf abortprox;
+
+void
+proxabort()
+{
+ extern int proxy;
+
+ if (!proxy) {
+ pswitch(1);
+ }
+ if (connected) {
+ proxflag = 1;
+ }
+ else {
+ proxflag = 0;
+ }
+ pswitch(0);
+ longjmp(abortprox,1);
+}
+
+doproxy(argc,argv)
+ int argc;
+ char *argv[];
+{
+ extern struct cmd cmdtab[];
+ extern jmp_buf abortprox;
+ register struct cmd *c;
+ struct cmd *getcmd();
+ sig_t oldintr;
+ void proxabort();
+
+ if (argc < 2 && !another(&argc, &argv, "command")) {
+ printf("usage: %s command\n", argv[0]);
+ code = -1;
+ return;
+ }
+ c = getcmd(argv[1]);
+ if (c == (struct cmd *) -1) {
+ printf("?Ambiguous command\n");
+ (void) fflush(stdout);
+ code = -1;
+ return;
+ }
+ if (c == 0) {
+ printf("?Invalid command\n");
+ (void) fflush(stdout);
+ code = -1;
+ return;
+ }
+ if (!c->c_proxy) {
+ printf("?Invalid proxy command\n");
+ (void) fflush(stdout);
+ code = -1;
+ return;
+ }
+ if (setjmp(abortprox)) {
+ code = -1;
+ return;
+ }
+ oldintr = signal(SIGINT, proxabort);
+ pswitch(1);
+ if (c->c_conn && !connected) {
+ printf("Not connected\n");
+ (void) fflush(stdout);
+ pswitch(0);
+ (void) signal(SIGINT, oldintr);
+ code = -1;
+ return;
+ }
+ (*c->c_handler)(argc-1, argv+1);
+ if (connected) {
+ proxflag = 1;
+ }
+ else {
+ proxflag = 0;
+ }
+ pswitch(0);
+ (void) signal(SIGINT, oldintr);
+}
+
+setcase()
+{
+ mcase = !mcase;
+ printf("Case mapping %s.\n", onoff(mcase));
+ code = mcase;
+}
+
+setcr()
+{
+ crflag = !crflag;
+ printf("Carriage Return stripping %s.\n", onoff(crflag));
+ code = crflag;
+}
+
+setntrans(argc,argv)
+ int argc;
+ char *argv[];
+{
+ if (argc == 1) {
+ ntflag = 0;
+ printf("Ntrans off.\n");
+ code = ntflag;
+ return;
+ }
+ ntflag++;
+ code = ntflag;
+ (void) strncpy(ntin, argv[1], 16);
+ ntin[16] = '\0';
+ if (argc == 2) {
+ ntout[0] = '\0';
+ return;
+ }
+ (void) strncpy(ntout, argv[2], 16);
+ ntout[16] = '\0';
+}
+
+char *
+dotrans(name)
+ char *name;
+{
+ static char new[MAXPATHLEN];
+ char *cp1, *cp2 = new;
+ register int i, ostop, found;
+
+ for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++);
+ for (cp1 = name; *cp1; cp1++) {
+ found = 0;
+ for (i = 0; *(ntin + i) && i < 16; i++) {
+ if (*cp1 == *(ntin + i)) {
+ found++;
+ if (i < ostop) {
+ *cp2++ = *(ntout + i);
+ }
+ break;
+ }
+ }
+ if (!found) {
+ *cp2++ = *cp1;
+ }
+ }
+ *cp2 = '\0';
+ return(new);
+}
+
+setnmap(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char *cp;
+
+ if (argc == 1) {
+ mapflag = 0;
+ printf("Nmap off.\n");
+ code = mapflag;
+ return;
+ }
+ if (argc < 3 && !another(&argc, &argv, "mapout")) {
+ printf("Usage: %s [mapin mapout]\n",argv[0]);
+ code = -1;
+ return;
+ }
+ mapflag = 1;
+ code = 1;
+ cp = index(altarg, ' ');
+ if (proxy) {
+ while(*++cp == ' ');
+ altarg = cp;
+ cp = index(altarg, ' ');
+ }
+ *cp = '\0';
+ (void) strncpy(mapin, altarg, MAXPATHLEN - 1);
+ while (*++cp == ' ');
+ (void) strncpy(mapout, cp, MAXPATHLEN - 1);
+}
+
+char *
+domap(name)
+ char *name;
+{
+ static char new[MAXPATHLEN];
+ register char *cp1 = name, *cp2 = mapin;
+ char *tp[9], *te[9];
+ int i, toks[9], toknum = 0, match = 1;
+
+ for (i=0; i < 9; ++i) {
+ toks[i] = 0;
+ }
+ while (match && *cp1 && *cp2) {
+ switch (*cp2) {
+ case '\\':
+ if (*++cp2 != *cp1) {
+ match = 0;
+ }
+ break;
+ case '$':
+ if (*(cp2+1) >= '1' && (*cp2+1) <= '9') {
+ if (*cp1 != *(++cp2+1)) {
+ toks[toknum = *cp2 - '1']++;
+ tp[toknum] = cp1;
+ while (*++cp1 && *(cp2+1)
+ != *cp1);
+ te[toknum] = cp1;
+ }
+ cp2++;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ if (*cp2 != *cp1) {
+ match = 0;
+ }
+ break;
+ }
+ if (match && *cp1) {
+ cp1++;
+ }
+ if (match && *cp2) {
+ cp2++;
+ }
+ }
+ if (!match && *cp1) /* last token mismatch */
+ {
+ toks[toknum] = 0;
+ }
+ cp1 = new;
+ *cp1 = '\0';
+ cp2 = mapout;
+ while (*cp2) {
+ match = 0;
+ switch (*cp2) {
+ case '\\':
+ if (*(cp2 + 1)) {
+ *cp1++ = *++cp2;
+ }
+ break;
+ case '[':
+LOOP:
+ if (*++cp2 == '$' && isdigit(*(cp2+1))) {
+ if (*++cp2 == '0') {
+ char *cp3 = name;
+
+ while (*cp3) {
+ *cp1++ = *cp3++;
+ }
+ match = 1;
+ }
+ else if (toks[toknum = *cp2 - '1']) {
+ char *cp3 = tp[toknum];
+
+ while (cp3 != te[toknum]) {
+ *cp1++ = *cp3++;
+ }
+ match = 1;
+ }
+ }
+ else {
+ while (*cp2 && *cp2 != ',' &&
+ *cp2 != ']') {
+ if (*cp2 == '\\') {
+ cp2++;
+ }
+ else if (*cp2 == '$' &&
+ isdigit(*(cp2+1))) {
+ if (*++cp2 == '0') {
+ char *cp3 = name;
+
+ while (*cp3) {
+ *cp1++ = *cp3++;
+ }
+ }
+ else if (toks[toknum =
+ *cp2 - '1']) {
+ char *cp3=tp[toknum];
+
+ while (cp3 !=
+ te[toknum]) {
+ *cp1++ = *cp3++;
+ }
+ }
+ }
+ else if (*cp2) {
+ *cp1++ = *cp2++;
+ }
+ }
+ if (!*cp2) {
+ printf("nmap: unbalanced brackets\n");
+ return(name);
+ }
+ match = 1;
+ cp2--;
+ }
+ if (match) {
+ while (*++cp2 && *cp2 != ']') {
+ if (*cp2 == '\\' && *(cp2 + 1)) {
+ cp2++;
+ }
+ }
+ if (!*cp2) {
+ printf("nmap: unbalanced brackets\n");
+ return(name);
+ }
+ break;
+ }
+ switch (*++cp2) {
+ case ',':
+ goto LOOP;
+ case ']':
+ break;
+ default:
+ cp2--;
+ goto LOOP;
+ }
+ break;
+ case '$':
+ if (isdigit(*(cp2 + 1))) {
+ if (*++cp2 == '0') {
+ char *cp3 = name;
+
+ while (*cp3) {
+ *cp1++ = *cp3++;
+ }
+ }
+ else if (toks[toknum = *cp2 - '1']) {
+ char *cp3 = tp[toknum];
+
+ while (cp3 != te[toknum]) {
+ *cp1++ = *cp3++;
+ }
+ }
+ break;
+ }
+ /* intentional drop through */
+ default:
+ *cp1++ = *cp2;
+ break;
+ }
+ cp2++;
+ }
+ *cp1 = '\0';
+ if (!*new) {
+ return(name);
+ }
+ return(new);
+}
+
+setsunique()
+{
+ sunique = !sunique;
+ printf("Store unique %s.\n", onoff(sunique));
+ code = sunique;
+}
+
+setrunique()
+{
+ runique = !runique;
+ printf("Receive unique %s.\n", onoff(runique));
+ code = runique;
+}
+
+/* change directory to perent directory */
+cdup()
+{
+ if (command("CDUP") == ERROR && code == 500) {
+ if (verbose)
+ printf("CDUP command not recognized, trying XCUP\n");
+ (void) command("XCUP");
+ }
+}
+
+/* restart transfer at specific point */
+restart(argc, argv)
+ int argc;
+ char *argv[];
+{
+ extern long atol();
+ if (argc != 2)
+ printf("restart: offset not specified\n");
+ else {
+ restart_point = atol(argv[1]);
+ printf("restarting at %ld. %s\n", restart_point,
+ "execute get, put or append to initiate transfer");
+ }
+}
+
+/* show remote system type */
+syst()
+{
+ (void) command("SYST");
+}
+
+macdef(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char *tmp;
+ int c;
+
+ if (macnum == 16) {
+ printf("Limit of 16 macros have already been defined\n");
+ code = -1;
+ return;
+ }
+ if (argc < 2 && !another(&argc, &argv, "macro name")) {
+ printf("Usage: %s macro_name\n",argv[0]);
+ code = -1;
+ return;
+ }
+ if (interactive) {
+ printf("Enter macro line by line, terminating it with a null line\n");
+ }
+ (void) strncpy(macros[macnum].mac_name, argv[1], 8);
+ if (macnum == 0) {
+ macros[macnum].mac_start = macbuf;
+ }
+ else {
+ macros[macnum].mac_start = macros[macnum - 1].mac_end + 1;
+ }
+ tmp = macros[macnum].mac_start;
+ while (tmp != macbuf+4096) {
+ if ((c = getchar()) == EOF) {
+ printf("macdef:end of file encountered\n");
+ code = -1;
+ return;
+ }
+ if ((*tmp = c) == '\n') {
+ if (tmp == macros[macnum].mac_start) {
+ macros[macnum++].mac_end = tmp;
+ code = 0;
+ return;
+ }
+ if (*(tmp-1) == '\0') {
+ macros[macnum++].mac_end = tmp - 1;
+ code = 0;
+ return;
+ }
+ *tmp = '\0';
+ }
+ tmp++;
+ }
+ while (1) {
+ while ((c = getchar()) != '\n' && c != EOF)
+ /* LOOP */;
+ if (c == EOF || getchar() == '\n') {
+ printf("Macro not defined - 4k buffer exceeded\n");
+ code = -1;
+ return;
+ }
+ }
+}
+
+/*
+ * get size of file on remote machine
+ */
+sizecmd(argc, argv)
+ int argc;
+ char *argv[];
+{
+
+ if (argc < 2 && !another(&argc, &argv, "filename")) {
+ printf("usage: %s filename\n", argv[0]);
+ code = -1;
+ return;
+ }
+ (void) command("SIZE %s", argv[1]);
+}
+
+/*
+ * get last modification time of file on remote machine
+ */
+modtime(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int overbose;
+
+ if (argc < 2 && !another(&argc, &argv, "filename")) {
+ printf("usage: %s filename\n", argv[0]);
+ code = -1;
+ return;
+ }
+ overbose = verbose;
+ if (debug == 0)
+ verbose = -1;
+ if (command("MDTM %s", argv[1]) == COMPLETE) {
+ int yy, mo, day, hour, min, sec;
+ sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo,
+ &day, &hour, &min, &sec);
+ /* might want to print this in local time */
+ printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1],
+ mo, day, yy, hour, min, sec);
+ } else
+ printf("%s\n", reply_string);
+ verbose = overbose;
+}
+
+/*
+ * show status on reomte machine
+ */
+rmtstatus(argc, argv)
+ int argc;
+ char *argv[];
+{
+ (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]);
+}
+
+/*
+ * get file if modtime is more recent than current file
+ */
+newer(argc, argv)
+ int argc;
+ char *argv[];
+{
+ if (getit(argc, argv, -1, "w"))
+ printf("Local file \"%s\" is newer than remote file \"%s\"\n",
+ argv[1], argv[2]);
+}