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