]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - crypto/heimdal/appl/ftp/ftp/domacro.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / crypto / heimdal / appl / ftp / ftp / domacro.c
1 /*
2  * Copyright (c) 1985, 1993, 1994
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by the University of
16  *      California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 #include "ftp_locl.h"
35 RCSID("$Id: domacro.c 14951 2005-04-25 13:09:26Z lha $");
36
37 void
38 domacro(int argc, char **argv)
39 {
40         int i, j, count = 2, loopflg = 0;
41         char *cp1, *cp2, line2[200];
42         struct cmd *c;
43
44         if (argc < 2 && !another(&argc, &argv, "macro name")) {
45                 printf("Usage: %s macro_name.\n", argv[0]);
46                 code = -1;
47                 return;
48         }
49         for (i = 0; i < macnum; ++i) {
50                 if (!strncmp(argv[1], macros[i].mac_name, 9)) {
51                         break;
52                 }
53         }
54         if (i == macnum) {
55                 printf("'%s' macro not found.\n", argv[1]);
56                 code = -1;
57                 return;
58         }
59         strlcpy(line2, line, sizeof(line2));
60 TOP:
61         cp1 = macros[i].mac_start;
62         while (cp1 != macros[i].mac_end) {
63                 while (isspace((unsigned char)*cp1)) {
64                         cp1++;
65                 }
66                 cp2 = line;
67                 while (*cp1 != '\0') {
68                       size_t len;
69                       switch(*cp1) {
70                             case '\\':
71                                 if (line + sizeof(line) - 2 < cp2)
72                                     goto out;
73                                 *cp2++ = *++cp1;
74                                  break;
75                             case '$':
76                                  if (isdigit((unsigned char)*(cp1+1))) {
77                                     j = 0;
78                                     while (isdigit((unsigned char)*++cp1)) {
79                                           j = 10*j +  *cp1 - '0';
80                                     }
81                                     cp1--;
82                                     if (argc - 2 >= j) {
83                                         len = sizeof(line) - (cp2 - line) - 1;
84                                         if (strlcpy(cp2, argv[j+1], len) >= len)
85                                             goto out;
86                                         cp2 += strlen(argv[j+1]);
87                                     }
88                                     break;
89                                  }
90                                  if (*(cp1+1) == 'i') {
91                                         loopflg = 1;
92                                         cp1++;
93                                         if (count < argc) {
94                                            len = sizeof(line) - (cp2 - line) - 1;
95                                            if (strlcpy(cp2, argv[count], len) >= len)
96                                                goto out;
97                                            cp2 += strlen(argv[count]);
98                                         }
99                                         break;
100                                 }
101                                 /* intentional drop through */
102                             default:
103                                 if (line + sizeof(line) - 2 < cp2)
104                                     goto out;
105                                 *cp2++ = *cp1;
106                                 break;
107                       }
108                       if (*cp1 != '\0') {
109                          cp1++;
110                       }
111                 }
112         out:
113                 *cp2 = '\0';
114                 makeargv();
115                 c = getcmd(margv[0]);
116                 if (c == (struct cmd *)-1) {
117                         printf("?Ambiguous command\n");
118                         code = -1;
119                 }
120                 else if (c == 0) {
121                         printf("?Invalid command\n");
122                         code = -1;
123                 }
124                 else if (c->c_conn && !connected) {
125                         printf("Not connected.\n");
126                         code = -1;
127                 }
128                 else {
129                         if (verbose) {
130                                 printf("%s\n",line);
131                         }
132                         (*c->c_handler)(margc, margv);
133                         if (bell && c->c_bell) {
134                                 putchar('\007');
135                         }
136                         strlcpy(line, line2, sizeof(line));
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 }