1185377Ssam/* 2187831Ssam * Copyright (c) 1985, 1993, 1994 3185377Ssam * The Regents of the University of California. All rights reserved. 4185377Ssam * 5185377Ssam * Redistribution and use in source and binary forms, with or without 6185377Ssam * modification, are permitted provided that the following conditions 7185377Ssam * are met: 8185377Ssam * 1. Redistributions of source code must retain the above copyright 9185377Ssam * notice, this list of conditions and the following disclaimer. 10185377Ssam * 2. Redistributions in binary form must reproduce the above copyright 11185377Ssam * notice, this list of conditions and the following disclaimer in the 12185377Ssam * documentation and/or other materials provided with the distribution. 13185377Ssam * 3. All advertising materials mentioning features or use of this software 14185377Ssam * must display the following acknowledgement: 15185377Ssam * This product includes software developed by the University of 16185377Ssam * California, Berkeley and its contributors. 17185907Ssam * 4. Neither the name of the University nor the names of its contributors 18185377Ssam * may be used to endorse or promote products derived from this software 19185377Ssam * without specific prior written permission. 20185377Ssam * 21185377Ssam * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22185377Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23185377Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24185377Ssam * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25185377Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26185377Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27185377Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28185377Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29185377Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30185377Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31185377Ssam * SUCH DAMAGE. 32185377Ssam */ 33185377Ssam 34185377Ssam#include "ftp_locl.h" 35185377SsamRCSID("$Id$"); 36185377Ssam 37185377Ssamvoid 38185377Ssamdomacro(int argc, char **argv) 39185377Ssam{ 40185377Ssam int i, j, count = 2, loopflg = 0; 41185377Ssam char *cp1, *cp2, line2[200]; 42185377Ssam struct cmd *c; 43185377Ssam 44185377Ssam if (argc < 2 && !another(&argc, &argv, "macro name")) { 45185377Ssam printf("Usage: %s macro_name.\n", argv[0]); 46185377Ssam code = -1; 47185377Ssam return; 48185377Ssam } 49185377Ssam for (i = 0; i < macnum; ++i) { 50185377Ssam if (!strncmp(argv[1], macros[i].mac_name, 9)) { 51185377Ssam break; 52185377Ssam } 53185377Ssam } 54185377Ssam if (i == macnum) { 55185377Ssam printf("'%s' macro not found.\n", argv[1]); 56185377Ssam code = -1; 57185377Ssam return; 58185377Ssam } 59185377Ssam strlcpy(line2, line, sizeof(line2)); 60185377SsamTOP: 61185377Ssam cp1 = macros[i].mac_start; 62185377Ssam while (cp1 != macros[i].mac_end) { 63185377Ssam while (isspace((unsigned char)*cp1)) { 64185377Ssam cp1++; 65185377Ssam } 66185377Ssam cp2 = line; 67185377Ssam while (*cp1 != '\0') { 68185377Ssam size_t len; 69185377Ssam switch(*cp1) { 70185377Ssam case '\\': 71185377Ssam if (line + sizeof(line) - 2 < cp2) 72185377Ssam goto out; 73185377Ssam *cp2++ = *++cp1; 74185380Ssam break; 75185380Ssam case '$': 76185380Ssam if (isdigit((unsigned char)*(cp1+1))) { 77185380Ssam j = 0; 78185380Ssam while (isdigit((unsigned char)*++cp1)) { 79185380Ssam j = 10*j + *cp1 - '0'; 80185380Ssam } 81185380Ssam cp1--; 82185380Ssam if (argc - 2 >= j) { 83185380Ssam len = sizeof(line) - (cp2 - line) - 1; 84185380Ssam if (strlcpy(cp2, argv[j+1], len) >= len) 85185380Ssam goto out; 86185380Ssam cp2 += strlen(argv[j+1]); 87185380Ssam } 88185380Ssam break; 89185380Ssam } 90185380Ssam if (*(cp1+1) == 'i') { 91185380Ssam loopflg = 1; 92185380Ssam cp1++; 93185380Ssam if (count < argc) { 94185380Ssam len = sizeof(line) - (cp2 - line) - 1; 95185380Ssam if (strlcpy(cp2, argv[count], len) >= len) 96185380Ssam goto out; 97185380Ssam cp2 += strlen(argv[count]); 98185380Ssam } 99185380Ssam break; 100185380Ssam } 101185380Ssam /* intentional drop through */ 102185380Ssam default: 103185380Ssam if (line + sizeof(line) - 2 < cp2) 104185380Ssam goto out; 105185380Ssam *cp2++ = *cp1; 106185380Ssam break; 107185377Ssam } 108185377Ssam if (*cp1 != '\0') { 109185377Ssam cp1++; 110185377Ssam } 111185377Ssam } 112185377Ssam out: 113185377Ssam *cp2 = '\0'; 114185377Ssam makeargv(); 115185377Ssam c = getcmd(margv[0]); 116185377Ssam if (c == (struct cmd *)-1) { 117185377Ssam printf("?Ambiguous command\n"); 118185377Ssam code = -1; 119185377Ssam } 120185377Ssam else if (c == 0) { 121185380Ssam printf("?Invalid command\n"); 122185380Ssam code = -1; 123185380Ssam } 124185380Ssam else if (c->c_conn && !connected) { 125185377Ssam printf("Not connected.\n"); 126185377Ssam code = -1; 127185377Ssam } 128185377Ssam else { 129185377Ssam if (verbose) { 130185377Ssam printf("%s\n",line); 131185377Ssam } 132185377Ssam (*c->c_handler)(margc, margv); 133185380Ssam if (bell && c->c_bell) { 134185380Ssam putchar('\007'); 135185380Ssam } 136185380Ssam strlcpy(line, line2, sizeof(line)); 137185377Ssam makeargv(); 138185377Ssam argc = margc; 139185377Ssam argv = margv; 140185377Ssam } 141185377Ssam if (cp1 != macros[i].mac_end) { 142185377Ssam cp1++; 143185377Ssam } 144185377Ssam } 145185377Ssam if (loopflg && ++count < argc) { 146185377Ssam goto TOP; 147185377Ssam } 148185377Ssam} 149185377Ssam