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