1 1.23 mrg /* $NetBSD: domacro.c,v 1.23 2019/02/03 03:19:29 mrg Exp $ */ 2 1.5 tls 3 1.1 cgd /* 4 1.3 cgd * Copyright (c) 1985, 1993, 1994 5 1.3 cgd * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * Redistribution and use in source and binary forms, with or without 8 1.1 cgd * modification, are permitted provided that the following conditions 9 1.1 cgd * are met: 10 1.1 cgd * 1. Redistributions of source code must retain the above copyright 11 1.1 cgd * notice, this list of conditions and the following disclaimer. 12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cgd * notice, this list of conditions and the following disclaimer in the 14 1.1 cgd * documentation and/or other materials provided with the distribution. 15 1.20 agc * 3. Neither the name of the University nor the names of its contributors 16 1.1 cgd * may be used to endorse or promote products derived from this software 17 1.1 cgd * without specific prior written permission. 18 1.1 cgd * 19 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 cgd * SUCH DAMAGE. 30 1.1 cgd */ 31 1.1 cgd 32 1.10 lukem #include <sys/cdefs.h> 33 1.1 cgd #ifndef lint 34 1.5 tls #if 0 35 1.5 tls static char sccsid[] = "@(#)domacro.c 8.3 (Berkeley) 4/2/94"; 36 1.5 tls #else 37 1.23 mrg __RCSID("$NetBSD: domacro.c,v 1.23 2019/02/03 03:19:29 mrg Exp $"); 38 1.5 tls #endif 39 1.1 cgd #endif /* not lint */ 40 1.1 cgd 41 1.3 cgd #include <ctype.h> 42 1.1 cgd #include <stdio.h> 43 1.8 lukem #include <string.h> 44 1.3 cgd 45 1.3 cgd #include "ftp_var.h" 46 1.1 cgd 47 1.3 cgd void 48 1.16 lukem domacro(int argc, char *argv[]) 49 1.1 cgd { 50 1.3 cgd int i, j, count = 2, loopflg = 0; 51 1.19 itojun char *cp1, *cp2, line2[FTPBUFLEN]; 52 1.3 cgd struct cmd *c; 53 1.22 lukem char cmdbuf[MAX_C_NAME]; 54 1.1 cgd 55 1.14 lukem if ((argc == 0 && argv != NULL) || 56 1.14 lukem (argc < 2 && !another(&argc, &argv, "macro name"))) { 57 1.21 christos UPRINTF("usage: %s macro_name [args]\n", argv[0]); 58 1.1 cgd code = -1; 59 1.1 cgd return; 60 1.1 cgd } 61 1.1 cgd for (i = 0; i < macnum; ++i) { 62 1.17 lukem if (!strncmp(argv[1], macros[i].mac_name, 9)) 63 1.1 cgd break; 64 1.1 cgd } 65 1.1 cgd if (i == macnum) { 66 1.12 lukem fprintf(ttyout, "'%s' macro not found.\n", argv[1]); 67 1.1 cgd code = -1; 68 1.1 cgd return; 69 1.1 cgd } 70 1.19 itojun (void)strlcpy(line2, line, sizeof(line2)); 71 1.17 lukem TOP: 72 1.1 cgd cp1 = macros[i].mac_start; 73 1.1 cgd while (cp1 != macros[i].mac_end) { 74 1.17 lukem while (isspace((unsigned char)*cp1)) 75 1.1 cgd cp1++; 76 1.1 cgd cp2 = line; 77 1.1 cgd while (*cp1 != '\0') { 78 1.17 lukem switch(*cp1) { 79 1.17 lukem case '\\': 80 1.17 lukem *cp2++ = *++cp1; 81 1.17 lukem break; 82 1.17 lukem case '$': 83 1.17 lukem if (isdigit((unsigned char)*(cp1+1))) { 84 1.17 lukem j = 0; 85 1.17 lukem while (isdigit((unsigned char)*++cp1)) 86 1.17 lukem j = 10*j + *cp1 - '0'; 87 1.17 lukem cp1--; 88 1.17 lukem if (argc - 2 >= j) { 89 1.19 itojun (void)strlcpy(cp2, argv[j+1], 90 1.19 itojun sizeof(line) - (cp2 - line)); 91 1.17 lukem cp2 += strlen(argv[j+1]); 92 1.17 lukem } 93 1.17 lukem break; 94 1.17 lukem } 95 1.17 lukem if (*(cp1+1) == 'i') { 96 1.1 cgd loopflg = 1; 97 1.1 cgd cp1++; 98 1.1 cgd if (count < argc) { 99 1.19 itojun (void)strlcpy(cp2, argv[count], 100 1.19 itojun sizeof(line) - (cp2 - line)); 101 1.17 lukem cp2 += strlen(argv[count]); 102 1.1 cgd } 103 1.1 cgd break; 104 1.1 cgd } 105 1.23 mrg /* FALLTHROUGH */ 106 1.17 lukem default: 107 1.1 cgd *cp2++ = *cp1; 108 1.1 cgd break; 109 1.17 lukem } 110 1.17 lukem if (*cp1 != '\0') 111 1.17 lukem cp1++; 112 1.1 cgd } 113 1.1 cgd *cp2 = '\0'; 114 1.1 cgd makeargv(); 115 1.1 cgd c = getcmd(margv[0]); 116 1.1 cgd if (c == (struct cmd *)-1) { 117 1.12 lukem fputs("?Ambiguous command.\n", ttyout); 118 1.1 cgd code = -1; 119 1.17 lukem } else if (c == 0) { 120 1.12 lukem fputs("?Invalid command.\n", ttyout); 121 1.1 cgd code = -1; 122 1.17 lukem } else if (c->c_conn && !connected) { 123 1.12 lukem fputs("Not connected.\n", ttyout); 124 1.1 cgd code = -1; 125 1.17 lukem } else { 126 1.12 lukem if (verbose) { 127 1.12 lukem fputs(line, ttyout); 128 1.12 lukem putc('\n', ttyout); 129 1.12 lukem } 130 1.22 lukem (void)strlcpy(cmdbuf, c->c_name, sizeof(cmdbuf)); 131 1.22 lukem margv[0] = cmdbuf; 132 1.1 cgd (*c->c_handler)(margc, margv); 133 1.17 lukem if (bell && c->c_bell) 134 1.12 lukem (void)putc('\007', ttyout); 135 1.19 itojun (void)strlcpy(line, line2, sizeof(line)); 136 1.1 cgd makeargv(); 137 1.1 cgd argc = margc; 138 1.1 cgd argv = margv; 139 1.1 cgd } 140 1.17 lukem if (cp1 != macros[i].mac_end) 141 1.1 cgd cp1++; 142 1.1 cgd } 143 1.17 lukem if (loopflg && ++count < argc) 144 1.1 cgd goto TOP; 145 1.1 cgd } 146