/* * Help/usage command. * Call each command handler with argc == 0 and argv[0] == name. */ void help(int argc, char *argv[]) { struct cmd *c; char *nargv[1], *cmd; const char *p; int isusage; cmd = argv[0]; isusage = (strcmp(cmd, "usage") == 0); if (argc == 0 || (isusage && argc == 1)) { UPRINTF("usage: %s [command [...]]\n", cmd); return; } if (argc == 1) { StringList *buf; buf = ftp_sl_init(); fprintf(ttyout, "%sommands may be abbreviated. Commands are:\n\n", proxy ? "Proxy c" : "C"); for (c = cmdtab; (p = c->c_name) != NULL; c++) if (!proxy || c->c_proxy) ftp_sl_add(buf, ftp_strdup(p)); list_vertical(buf); sl_free(buf, 1); return; } #define HELPINDENT ((int) sizeof("disconnect")) while (--argc > 0) { char *arg; char cmdbuf[MAX_C_NAME]; arg = *++argv; c = getcmd(arg); if (c == (struct cmd *)-1) fprintf(ttyout, "?Ambiguous %s command `%s'\n", cmd, arg); else if (c == NULL) fprintf(ttyout, "?Invalid %s command `%s'\n", cmd, arg); else { if (isusage) { (void)strlcpy(cmdbuf, c->c_name, sizeof(cmdbuf)); nargv[0] = cmdbuf; (*c->c_handler)(0, nargv); } else fprintf(ttyout, "%-*s\t%s\n", HELPINDENT, c->c_name, c->c_help); } } }
void domacro(int argc, char *argv[]) { int i, j, count = 2, loopflg = 0; char *cp1, *cp2, line2[FTPBUFLEN]; struct cmd *c; if ((argc == 0 && argv != NULL) || (argc < 2 && !another(&argc, &argv, "macro name"))) { UPRINTF("usage: %s macro_name [args]\n", argv[0]); code = -1; return; } for (i = 0; i < macnum; ++i) { if (!strncmp(argv[1], macros[i].mac_name, 9)) break; } if (i == macnum) { fprintf(ttyout, "'%s' macro not found.\n", argv[1]); code = -1; return; } (void)strlcpy(line2, line, sizeof(line2)); TOP: cp1 = macros[i].mac_start; while (cp1 != macros[i].mac_end) { while (isspace((unsigned char)*cp1)) cp1++; cp2 = line; while (*cp1 != '\0') { switch(*cp1) { case '\\': *cp2++ = *++cp1; break; case '$': if (isdigit((unsigned char)*(cp1+1))) { j = 0; while (isdigit((unsigned char)*++cp1)) j = 10*j + *cp1 - '0'; cp1--; if (argc - 2 >= j) { (void)strlcpy(cp2, argv[j+1], sizeof(line) - (cp2 - line)); cp2 += strlen(argv[j+1]); } break; } if (*(cp1+1) == 'i') { loopflg = 1; cp1++; if (count < argc) { (void)strlcpy(cp2, argv[count], sizeof(line) - (cp2 - line)); cp2 += strlen(argv[count]); } break; } /* intentional drop through */ default: *cp2++ = *cp1; break; } if (*cp1 != '\0') cp1++; } *cp2 = '\0'; makeargv(); c = getcmd(margv[0]); if (c == (struct cmd *)-1) { fputs("?Ambiguous command.\n", ttyout); code = -1; } else if (c == 0) { fputs("?Invalid command.\n", ttyout); code = -1; } else if (c->c_conn && !connected) { fputs("Not connected.\n", ttyout); code = -1; } else { if (verbose) { fputs(line, ttyout); putc('\n', ttyout); } margv[0] = c->c_name; (*c->c_handler)(margc, margv); if (bell && c->c_bell) (void)putc('\007', ttyout); (void)strlcpy(line, line2, sizeof(line)); makeargv(); argc = margc; argv = margv; } if (cp1 != macros[i].mac_end) cp1++; } if (loopflg && ++count < argc) goto TOP; }