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