1223328Sgavin/*	$NetBSD: domacro.c,v 1.8 2009/05/20 12:53:47 lukem Exp $	*/
2223328Sgavin/*	from	NetBSD: domacro.c,v 1.22 2009/04/12 10:18:52 lukem Exp	*/
379971Sobrien
479971Sobrien/*
579971Sobrien * Copyright (c) 1985, 1993, 1994
679971Sobrien *	The Regents of the University of California.  All rights reserved.
779971Sobrien *
879971Sobrien * Redistribution and use in source and binary forms, with or without
979971Sobrien * modification, are permitted provided that the following conditions
1079971Sobrien * are met:
1179971Sobrien * 1. Redistributions of source code must retain the above copyright
1279971Sobrien *    notice, this list of conditions and the following disclaimer.
1379971Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1479971Sobrien *    notice, this list of conditions and the following disclaimer in the
1579971Sobrien *    documentation and/or other materials provided with the distribution.
16121966Smikeh * 3. Neither the name of the University nor the names of its contributors
1779971Sobrien *    may be used to endorse or promote products derived from this software
1879971Sobrien *    without specific prior written permission.
1979971Sobrien *
2079971Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2179971Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2279971Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2379971Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2479971Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2579971Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2679971Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2779971Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2879971Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2979971Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3079971Sobrien * SUCH DAMAGE.
3179971Sobrien */
3279971Sobrien
33223328Sgavin#include "tnftp.h"
34223328Sgavin
35223328Sgavin#if 0	/* tnftp */
36223328Sgavin
37116424Smikeh#include <sys/cdefs.h>
38116424Smikeh#ifndef lint
39116424Smikeh#if 0
40116424Smikehstatic char sccsid[] = "@(#)domacro.c	8.3 (Berkeley) 4/2/94";
41116424Smikeh#else
42223328Sgavin__RCSID(" NetBSD: domacro.c,v 1.22 2009/04/12 10:18:52 lukem Exp  ");
43116424Smikeh#endif
44116424Smikeh#endif /* not lint */
4579971Sobrien
46116424Smikeh#include <ctype.h>
47116424Smikeh#include <stdio.h>
48116424Smikeh#include <string.h>
49116424Smikeh
50223328Sgavin#endif	/* tnftp */
51223328Sgavin
5279971Sobrien#include "ftp_var.h"
5379971Sobrien
5479971Sobrienvoid
5579971Sobriendomacro(int argc, char *argv[])
5679971Sobrien{
5779971Sobrien	int i, j, count = 2, loopflg = 0;
5898247Smikeh	char *cp1, *cp2, line2[FTPBUFLEN];
5979971Sobrien	struct cmd *c;
60223328Sgavin	char cmdbuf[MAX_C_NAME];
6179971Sobrien
6279971Sobrien	if ((argc == 0 && argv != NULL) ||
6379971Sobrien	    (argc < 2 && !another(&argc, &argv, "macro name"))) {
64223328Sgavin		UPRINTF("usage: %s macro_name [args]\n", argv[0]);
6579971Sobrien		code = -1;
6679971Sobrien		return;
6779971Sobrien	}
6879971Sobrien	for (i = 0; i < macnum; ++i) {
6979971Sobrien		if (!strncmp(argv[1], macros[i].mac_name, 9))
7079971Sobrien			break;
7179971Sobrien	}
7279971Sobrien	if (i == macnum) {
7379971Sobrien		fprintf(ttyout, "'%s' macro not found.\n", argv[1]);
7479971Sobrien		code = -1;
7579971Sobrien		return;
7679971Sobrien	}
7798247Smikeh	(void)strlcpy(line2, line, sizeof(line2));
7879971Sobrien TOP:
7979971Sobrien	cp1 = macros[i].mac_start;
8079971Sobrien	while (cp1 != macros[i].mac_end) {
8179971Sobrien		while (isspace((unsigned char)*cp1))
8279971Sobrien			cp1++;
8379971Sobrien		cp2 = line;
8479971Sobrien		while (*cp1 != '\0') {
8579971Sobrien			switch(*cp1) {
8679971Sobrien			case '\\':
8779971Sobrien				*cp2++ = *++cp1;
8879971Sobrien				break;
8979971Sobrien			case '$':
9079971Sobrien				if (isdigit((unsigned char)*(cp1+1))) {
9179971Sobrien					j = 0;
9279971Sobrien					while (isdigit((unsigned char)*++cp1))
9379971Sobrien						j = 10*j +  *cp1 - '0';
9479971Sobrien					cp1--;
9579971Sobrien					if (argc - 2 >= j) {
9698247Smikeh						(void)strlcpy(cp2, argv[j+1],
9798247Smikeh						    sizeof(line) - (cp2 - line));
9879971Sobrien						cp2 += strlen(argv[j+1]);
9979971Sobrien					}
10079971Sobrien					break;
10179971Sobrien				}
10279971Sobrien				if (*(cp1+1) == 'i') {
10379971Sobrien					loopflg = 1;
10479971Sobrien					cp1++;
10579971Sobrien					if (count < argc) {
10698247Smikeh						(void)strlcpy(cp2, argv[count],
10798247Smikeh						    sizeof(line) - (cp2 - line));
10879971Sobrien						cp2 += strlen(argv[count]);
10979971Sobrien					}
11079971Sobrien					break;
11179971Sobrien				}
11279971Sobrien				/* intentional drop through */
11379971Sobrien			default:
11479971Sobrien				*cp2++ = *cp1;
11579971Sobrien				break;
11679971Sobrien			}
11779971Sobrien			if (*cp1 != '\0')
11879971Sobrien				cp1++;
11979971Sobrien		}
12079971Sobrien		*cp2 = '\0';
12179971Sobrien		makeargv();
12279971Sobrien		c = getcmd(margv[0]);
12379971Sobrien		if (c == (struct cmd *)-1) {
12479971Sobrien			fputs("?Ambiguous command.\n", ttyout);
12579971Sobrien			code = -1;
12679971Sobrien		} else if (c == 0) {
12779971Sobrien			fputs("?Invalid command.\n", ttyout);
12879971Sobrien			code = -1;
12979971Sobrien		} else if (c->c_conn && !connected) {
13079971Sobrien			fputs("Not connected.\n", ttyout);
13179971Sobrien			code = -1;
13279971Sobrien		} else {
13379971Sobrien			if (verbose) {
13479971Sobrien				fputs(line, ttyout);
13579971Sobrien				putc('\n', ttyout);
13679971Sobrien			}
137223328Sgavin			(void)strlcpy(cmdbuf, c->c_name, sizeof(cmdbuf));
138223328Sgavin			margv[0] = cmdbuf;
13979971Sobrien			(*c->c_handler)(margc, margv);
14079971Sobrien			if (bell && c->c_bell)
14179971Sobrien				(void)putc('\007', ttyout);
14298247Smikeh			(void)strlcpy(line, line2, sizeof(line));
14379971Sobrien			makeargv();
14479971Sobrien			argc = margc;
14579971Sobrien			argv = margv;
14679971Sobrien		}
14779971Sobrien		if (cp1 != macros[i].mac_end)
14879971Sobrien			cp1++;
14979971Sobrien	}
15079971Sobrien	if (loopflg && ++count < argc)
15179971Sobrien		goto TOP;
15279971Sobrien}
153