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