xref: /original-bsd/usr.bin/ftp/domacro.c (revision 9a897be2)
1 /*
2  * Copyright (c) 1985 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)domacro.c	1.7 (Berkeley) 06/01/90";
10 #endif /* not lint */
11 
12 #include "ftp_var.h"
13 
14 #include <signal.h>
15 #include <stdio.h>
16 #include <errno.h>
17 #include <ctype.h>
18 #include <sys/ttychars.h>
19 
20 domacro(argc, argv)
21 	int argc;
22 	char *argv[];
23 {
24 	register int i, j;
25 	register char *cp1, *cp2;
26 	int count = 2, loopflg = 0;
27 	char line2[200];
28 	extern char **glob(), *globerr;
29 	struct cmd *getcmd(), *c;
30 	extern struct cmd cmdtab[];
31 
32 	if (argc < 2) {
33 		(void) strcat(line, " ");
34 		printf("(macro name) ");
35 		(void) gets(&line[strlen(line)]);
36 		makeargv();
37 		argc = margc;
38 		argv = margv;
39 	}
40 	if (argc < 2) {
41 		printf("Usage: %s macro_name.\n", argv[0]);
42 		code = -1;
43 		return;
44 	}
45 	for (i = 0; i < macnum; ++i) {
46 		if (!strncmp(argv[1], macros[i].mac_name, 9)) {
47 			break;
48 		}
49 	}
50 	if (i == macnum) {
51 		printf("'%s' macro not found.\n", argv[1]);
52 		code = -1;
53 		return;
54 	}
55 	(void) strcpy(line2, line);
56 TOP:
57 	cp1 = macros[i].mac_start;
58 	while (cp1 != macros[i].mac_end) {
59 		while (isspace(*cp1)) {
60 			cp1++;
61 		}
62 		cp2 = line;
63 		while (*cp1 != '\0') {
64 		      switch(*cp1) {
65 		   	    case '\\':
66 				 *cp2++ = *++cp1;
67 				 break;
68 			    case '$':
69 				 if (isdigit(*(cp1+1))) {
70 				    j = 0;
71 				    while (isdigit(*++cp1)) {
72 					  j = 10*j +  *cp1 - '0';
73 				    }
74 				    cp1--;
75 				    if (argc - 2 >= j) {
76 					(void) strcpy(cp2, argv[j+1]);
77 					cp2 += strlen(argv[j+1]);
78 				    }
79 				    break;
80 				 }
81 				 if (*(cp1+1) == 'i') {
82 					loopflg = 1;
83 					cp1++;
84 					if (count < argc) {
85 					   (void) strcpy(cp2, argv[count]);
86 					   cp2 += strlen(argv[count]);
87 					}
88 					break;
89 				}
90 				/* intentional drop through */
91 			    default:
92 				*cp2++ = *cp1;
93 				break;
94 		      }
95 		      if (*cp1 != '\0') {
96 			 cp1++;
97 		      }
98 		}
99 		*cp2 = '\0';
100 		makeargv();
101 		c = getcmd(margv[0]);
102 		if (c == (struct cmd *)-1) {
103 			printf("?Ambiguous command\n");
104 			code = -1;
105 		}
106 		else if (c == 0) {
107 			printf("?Invalid command\n");
108 			code = -1;
109 		}
110 		else if (c->c_conn && !connected) {
111 			printf("Not connected.\n");
112 			code = -1;
113 		}
114 		else {
115 			if (verbose) {
116 				printf("%s\n",line);
117 			}
118 			(*c->c_handler)(margc, margv);
119 			if (bell && c->c_bell) {
120 				(void) putchar('\007');
121 			}
122 			(void) strcpy(line, line2);
123 			makeargv();
124 			argc = margc;
125 			argv = margv;
126 		}
127 		if (cp1 != macros[i].mac_end) {
128 			cp1++;
129 		}
130 	}
131 	if (loopflg && ++count < argc) {
132 		goto TOP;
133 	}
134 }
135