/ appl / ftp / ftp / domacro.c
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$");
 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  }