1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  *	Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  *	Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
28*7c478bd9Sstevel@tonic-gate /*	All Rights Reserved  	*/
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate /*
31*7c478bd9Sstevel@tonic-gate  *	University Copyright- Copyright (c) 1982, 1986, 1988
32*7c478bd9Sstevel@tonic-gate  *	The Regents of the University of California
33*7c478bd9Sstevel@tonic-gate  *	All Rights Reserved
34*7c478bd9Sstevel@tonic-gate  *
35*7c478bd9Sstevel@tonic-gate  *	University Acknowledgment- Portions of this document are derived from
36*7c478bd9Sstevel@tonic-gate  *	software developed by the University of California, Berkeley, and its
37*7c478bd9Sstevel@tonic-gate  *	contributors.
38*7c478bd9Sstevel@tonic-gate  */
39*7c478bd9Sstevel@tonic-gate 
40*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
41*7c478bd9Sstevel@tonic-gate 
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate /*
44*7c478bd9Sstevel@tonic-gate  * FTP User Program -- Command Routines.
45*7c478bd9Sstevel@tonic-gate  */
46*7c478bd9Sstevel@tonic-gate #define	FTP_NAMES
47*7c478bd9Sstevel@tonic-gate #include "ftp_var.h"
48*7c478bd9Sstevel@tonic-gate 
49*7c478bd9Sstevel@tonic-gate FILE	*tmp_nlst = NULL;	/* tmp file; holds NLST results for mget, etc */
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate static char *mname;
52*7c478bd9Sstevel@tonic-gate static jmp_buf jabort;
53*7c478bd9Sstevel@tonic-gate static jmp_buf abortprox;
54*7c478bd9Sstevel@tonic-gate 
55*7c478bd9Sstevel@tonic-gate static char *remglob(char *argv[], int doswitch);
56*7c478bd9Sstevel@tonic-gate static char *onoff(int bool);
57*7c478bd9Sstevel@tonic-gate static int confirm(char *cmd, char *file);
58*7c478bd9Sstevel@tonic-gate static int globulize(char **cpp);
59*7c478bd9Sstevel@tonic-gate static void proxabort(int sig);
60*7c478bd9Sstevel@tonic-gate static void mabort(int sig);
61*7c478bd9Sstevel@tonic-gate static char *dotrans(char *name);
62*7c478bd9Sstevel@tonic-gate static char *domap(char *name);
63*7c478bd9Sstevel@tonic-gate static void getit(int argc, char *argv[], int restartit, char *mode);
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate static char *getlevel(int);
66*7c478bd9Sstevel@tonic-gate 
67*7c478bd9Sstevel@tonic-gate /* Prompt for command argument, add to buffer with space separator */
68*7c478bd9Sstevel@tonic-gate static int
69*7c478bd9Sstevel@tonic-gate prompt_for_arg(char *buffer, int buffer_size, char *prompt)
70*7c478bd9Sstevel@tonic-gate {
71*7c478bd9Sstevel@tonic-gate 	if (strlen(buffer) > buffer_size - 2) {
72*7c478bd9Sstevel@tonic-gate 		(void) printf("Line too long\n");
73*7c478bd9Sstevel@tonic-gate 		return (-1);
74*7c478bd9Sstevel@tonic-gate 	}
75*7c478bd9Sstevel@tonic-gate 	strcat(buffer, " ");
76*7c478bd9Sstevel@tonic-gate 	stop_timer();
77*7c478bd9Sstevel@tonic-gate 	(void) printf("(%s) ", prompt);
78*7c478bd9Sstevel@tonic-gate 	if (fgets(buffer + strlen(buffer), buffer_size - strlen(buffer), stdin)
79*7c478bd9Sstevel@tonic-gate 	    == NULL) {
80*7c478bd9Sstevel@tonic-gate 		reset_timer();
81*7c478bd9Sstevel@tonic-gate 		return (-1);
82*7c478bd9Sstevel@tonic-gate 	}
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate 	/* Flush what didn't fit in the buffer */
85*7c478bd9Sstevel@tonic-gate 	if (buffer[strlen(buffer)-1] != '\n') {
86*7c478bd9Sstevel@tonic-gate 		while (fgetc(stdin) != '\n' && !ferror(stdin) && !feof(stdin))
87*7c478bd9Sstevel@tonic-gate 			;
88*7c478bd9Sstevel@tonic-gate 		(void) printf("Line too long\n");
89*7c478bd9Sstevel@tonic-gate 		reset_timer();
90*7c478bd9Sstevel@tonic-gate 		return (-1);
91*7c478bd9Sstevel@tonic-gate 	} else
92*7c478bd9Sstevel@tonic-gate 		buffer[strlen(buffer)-1] = 0;
93*7c478bd9Sstevel@tonic-gate 
94*7c478bd9Sstevel@tonic-gate 	reset_timer();
95*7c478bd9Sstevel@tonic-gate 	return (0);
96*7c478bd9Sstevel@tonic-gate }
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate 
99*7c478bd9Sstevel@tonic-gate /*
100*7c478bd9Sstevel@tonic-gate  * Connect to peer server and
101*7c478bd9Sstevel@tonic-gate  * auto-login, if possible.
102*7c478bd9Sstevel@tonic-gate  */
103*7c478bd9Sstevel@tonic-gate void
104*7c478bd9Sstevel@tonic-gate setpeer(int argc, char *argv[])
105*7c478bd9Sstevel@tonic-gate {
106*7c478bd9Sstevel@tonic-gate 	char *host;
107*7c478bd9Sstevel@tonic-gate 
108*7c478bd9Sstevel@tonic-gate 	if (connected) {
109*7c478bd9Sstevel@tonic-gate 		(void) printf("Already connected to %s, use close first.\n",
110*7c478bd9Sstevel@tonic-gate 			hostname);
111*7c478bd9Sstevel@tonic-gate 		code = -1;
112*7c478bd9Sstevel@tonic-gate 		return;
113*7c478bd9Sstevel@tonic-gate 	}
114*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
115*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "to") == -1) {
116*7c478bd9Sstevel@tonic-gate 			code = -1;
117*7c478bd9Sstevel@tonic-gate 			return;
118*7c478bd9Sstevel@tonic-gate 		}
119*7c478bd9Sstevel@tonic-gate 		makeargv();
120*7c478bd9Sstevel@tonic-gate 		argc = margc;
121*7c478bd9Sstevel@tonic-gate 		argv = margv;
122*7c478bd9Sstevel@tonic-gate 	}
123*7c478bd9Sstevel@tonic-gate 	if (argc > 3 || argc < 2) {
124*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s host-name [port]\n", argv[0]);
125*7c478bd9Sstevel@tonic-gate 		code = -1;
126*7c478bd9Sstevel@tonic-gate 		return;
127*7c478bd9Sstevel@tonic-gate 	}
128*7c478bd9Sstevel@tonic-gate 	strcpy(typename, "ascii");
129*7c478bd9Sstevel@tonic-gate 	host = hookup(argv[1], (argc > 2 ? argv[2] : "ftp"));
130*7c478bd9Sstevel@tonic-gate 	if (host) {
131*7c478bd9Sstevel@tonic-gate 		int overbose;
132*7c478bd9Sstevel@tonic-gate 		extern char reply_string[];
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate 		connected = 1;
135*7c478bd9Sstevel@tonic-gate 		/*
136*7c478bd9Sstevel@tonic-gate 		 * Set up defaults for FTP.
137*7c478bd9Sstevel@tonic-gate 		 */
138*7c478bd9Sstevel@tonic-gate 		clevel = dlevel = PROT_C;
139*7c478bd9Sstevel@tonic-gate 		if (autoauth) {
140*7c478bd9Sstevel@tonic-gate 			if (do_auth() && autoencrypt) {
141*7c478bd9Sstevel@tonic-gate 			    clevel = PROT_P;
142*7c478bd9Sstevel@tonic-gate 			    setpbsz(1<<20);
143*7c478bd9Sstevel@tonic-gate 			    if (command("PROT P") == COMPLETE)
144*7c478bd9Sstevel@tonic-gate 				dlevel = PROT_P;
145*7c478bd9Sstevel@tonic-gate 			    else {
146*7c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
147*7c478bd9Sstevel@tonic-gate 					"%s: couldn't enable encryption\n",
148*7c478bd9Sstevel@tonic-gate 					argv[0]);
149*7c478bd9Sstevel@tonic-gate 				/* unable to encrypt command channel, too! */
150*7c478bd9Sstevel@tonic-gate 				dlevel = clevel = PROT_C;
151*7c478bd9Sstevel@tonic-gate 			    }
152*7c478bd9Sstevel@tonic-gate 			}
153*7c478bd9Sstevel@tonic-gate 			if ((auth_type != AUTHTYPE_NONE) && (clevel == PROT_C))
154*7c478bd9Sstevel@tonic-gate 				clevel = PROT_S;
155*7c478bd9Sstevel@tonic-gate 		}
156*7c478bd9Sstevel@tonic-gate 
157*7c478bd9Sstevel@tonic-gate 		if (autologin)
158*7c478bd9Sstevel@tonic-gate 			(void) login(argv[1]);
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate 		overbose = verbose;
161*7c478bd9Sstevel@tonic-gate 		if (debug == 0)
162*7c478bd9Sstevel@tonic-gate 			verbose = -1;
163*7c478bd9Sstevel@tonic-gate 		if (command("SYST") == COMPLETE && overbose) {
164*7c478bd9Sstevel@tonic-gate 			char *cp, c;
165*7c478bd9Sstevel@tonic-gate 
166*7c478bd9Sstevel@tonic-gate 			cp = index(reply_string+4, ' ');
167*7c478bd9Sstevel@tonic-gate 			if (cp == NULL)
168*7c478bd9Sstevel@tonic-gate 				cp = index(reply_string+4, '\r');
169*7c478bd9Sstevel@tonic-gate 			if (cp) {
170*7c478bd9Sstevel@tonic-gate 				if (cp[-1] == '.')
171*7c478bd9Sstevel@tonic-gate 					cp--;
172*7c478bd9Sstevel@tonic-gate 				c = *cp;
173*7c478bd9Sstevel@tonic-gate 				*cp = '\0';
174*7c478bd9Sstevel@tonic-gate 			}
175*7c478bd9Sstevel@tonic-gate 
176*7c478bd9Sstevel@tonic-gate 			(void) printf("Remote system type is %s.\n",
177*7c478bd9Sstevel@tonic-gate 				reply_string+4);
178*7c478bd9Sstevel@tonic-gate 			if (cp)
179*7c478bd9Sstevel@tonic-gate 				*cp = c;
180*7c478bd9Sstevel@tonic-gate 		}
181*7c478bd9Sstevel@tonic-gate 		if (strncmp(reply_string, "215 UNIX Type: L8", 17) == 0) {
182*7c478bd9Sstevel@tonic-gate 			setbinary(0, NULL);
183*7c478bd9Sstevel@tonic-gate 			if (overbose)
184*7c478bd9Sstevel@tonic-gate 				(void) printf(
185*7c478bd9Sstevel@tonic-gate 				    "Using %s mode to transfer files.\n",
186*7c478bd9Sstevel@tonic-gate 				    typename);
187*7c478bd9Sstevel@tonic-gate 		} else if (overbose &&
188*7c478bd9Sstevel@tonic-gate 		    strncmp(reply_string, "215 TOPS20", 10) == 0) {
189*7c478bd9Sstevel@tonic-gate 			(void) printf(
190*7c478bd9Sstevel@tonic-gate 			    "Remember to set tenex mode when transfering "
191*7c478bd9Sstevel@tonic-gate 			    "binary files from this machine.\n");
192*7c478bd9Sstevel@tonic-gate 		}
193*7c478bd9Sstevel@tonic-gate 		verbose = overbose;
194*7c478bd9Sstevel@tonic-gate 	}
195*7c478bd9Sstevel@tonic-gate }
196*7c478bd9Sstevel@tonic-gate 
197*7c478bd9Sstevel@tonic-gate static struct types {
198*7c478bd9Sstevel@tonic-gate 	char	*t_name;
199*7c478bd9Sstevel@tonic-gate 	char	*t_mode;
200*7c478bd9Sstevel@tonic-gate 	int	t_type;
201*7c478bd9Sstevel@tonic-gate 	char	*t_arg;
202*7c478bd9Sstevel@tonic-gate } types[] = {
203*7c478bd9Sstevel@tonic-gate 	{ "ascii",	"A",	TYPE_A,	0 },
204*7c478bd9Sstevel@tonic-gate 	{ "binary",	"I",	TYPE_I,	0 },
205*7c478bd9Sstevel@tonic-gate 	{ "image",	"I",	TYPE_I,	0 },
206*7c478bd9Sstevel@tonic-gate 	{ "ebcdic",	"E",	TYPE_E,	0 },
207*7c478bd9Sstevel@tonic-gate 	{ "tenex",	"L",	TYPE_L,	bytename },
208*7c478bd9Sstevel@tonic-gate 	0
209*7c478bd9Sstevel@tonic-gate };
210*7c478bd9Sstevel@tonic-gate 
211*7c478bd9Sstevel@tonic-gate /*
212*7c478bd9Sstevel@tonic-gate  * Set transfer type.
213*7c478bd9Sstevel@tonic-gate  */
214*7c478bd9Sstevel@tonic-gate void
215*7c478bd9Sstevel@tonic-gate settype(int argc, char *argv[])
216*7c478bd9Sstevel@tonic-gate {
217*7c478bd9Sstevel@tonic-gate 	struct types *p;
218*7c478bd9Sstevel@tonic-gate 	int comret;
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate 	if (argc > 2) {
221*7c478bd9Sstevel@tonic-gate 		char *sep;
222*7c478bd9Sstevel@tonic-gate 
223*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s [", argv[0]);
224*7c478bd9Sstevel@tonic-gate 		sep = " ";
225*7c478bd9Sstevel@tonic-gate 		for (p = types; p->t_name; p++) {
226*7c478bd9Sstevel@tonic-gate 			(void) printf("%s%s", sep, p->t_name);
227*7c478bd9Sstevel@tonic-gate 			if (*sep == ' ')
228*7c478bd9Sstevel@tonic-gate 				sep = " | ";
229*7c478bd9Sstevel@tonic-gate 		}
230*7c478bd9Sstevel@tonic-gate 		(void) printf(" ]\n");
231*7c478bd9Sstevel@tonic-gate 		code = -1;
232*7c478bd9Sstevel@tonic-gate 		return;
233*7c478bd9Sstevel@tonic-gate 	}
234*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
235*7c478bd9Sstevel@tonic-gate 		(void) printf("Using %s mode to transfer files.\n", typename);
236*7c478bd9Sstevel@tonic-gate 		code = 0;
237*7c478bd9Sstevel@tonic-gate 		return;
238*7c478bd9Sstevel@tonic-gate 	}
239*7c478bd9Sstevel@tonic-gate 	for (p = types; p->t_name; p++)
240*7c478bd9Sstevel@tonic-gate 		if (strcmp(argv[1], p->t_name) == 0)
241*7c478bd9Sstevel@tonic-gate 			break;
242*7c478bd9Sstevel@tonic-gate 	if (p->t_name == 0) {
243*7c478bd9Sstevel@tonic-gate 		(void) printf("%s: unknown mode\n", argv[1]);
244*7c478bd9Sstevel@tonic-gate 		code = -1;
245*7c478bd9Sstevel@tonic-gate 		return;
246*7c478bd9Sstevel@tonic-gate 	}
247*7c478bd9Sstevel@tonic-gate 	if ((p->t_arg != NULL) && (*(p->t_arg) != '\0'))
248*7c478bd9Sstevel@tonic-gate 		comret = command("TYPE %s %s", p->t_mode, p->t_arg);
249*7c478bd9Sstevel@tonic-gate 	else
250*7c478bd9Sstevel@tonic-gate 		comret = command("TYPE %s", p->t_mode);
251*7c478bd9Sstevel@tonic-gate 	if (comret == COMPLETE) {
252*7c478bd9Sstevel@tonic-gate 		(void) strcpy(typename, p->t_name);
253*7c478bd9Sstevel@tonic-gate 		type = p->t_type;
254*7c478bd9Sstevel@tonic-gate 	}
255*7c478bd9Sstevel@tonic-gate }
256*7c478bd9Sstevel@tonic-gate 
257*7c478bd9Sstevel@tonic-gate /*
258*7c478bd9Sstevel@tonic-gate  * Set binary transfer type.
259*7c478bd9Sstevel@tonic-gate  */
260*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
261*7c478bd9Sstevel@tonic-gate void
262*7c478bd9Sstevel@tonic-gate setbinary(int argc, char *argv[])
263*7c478bd9Sstevel@tonic-gate {
264*7c478bd9Sstevel@tonic-gate 	call(settype, "type", "binary", 0);
265*7c478bd9Sstevel@tonic-gate }
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate /*
268*7c478bd9Sstevel@tonic-gate  * Set ascii transfer type.
269*7c478bd9Sstevel@tonic-gate  */
270*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
271*7c478bd9Sstevel@tonic-gate void
272*7c478bd9Sstevel@tonic-gate setascii(int argc, char *argv[])
273*7c478bd9Sstevel@tonic-gate {
274*7c478bd9Sstevel@tonic-gate 	call(settype, "type", "ascii", 0);
275*7c478bd9Sstevel@tonic-gate }
276*7c478bd9Sstevel@tonic-gate 
277*7c478bd9Sstevel@tonic-gate /*
278*7c478bd9Sstevel@tonic-gate  * Set tenex transfer type.
279*7c478bd9Sstevel@tonic-gate  */
280*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
281*7c478bd9Sstevel@tonic-gate void
282*7c478bd9Sstevel@tonic-gate settenex(int argc, char *argv[])
283*7c478bd9Sstevel@tonic-gate {
284*7c478bd9Sstevel@tonic-gate 	call(settype, "type", "tenex", 0);
285*7c478bd9Sstevel@tonic-gate }
286*7c478bd9Sstevel@tonic-gate 
287*7c478bd9Sstevel@tonic-gate /*
288*7c478bd9Sstevel@tonic-gate  * Set ebcdic transfer type.
289*7c478bd9Sstevel@tonic-gate  */
290*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
291*7c478bd9Sstevel@tonic-gate void
292*7c478bd9Sstevel@tonic-gate setebcdic(int argc, char *argv[])
293*7c478bd9Sstevel@tonic-gate {
294*7c478bd9Sstevel@tonic-gate 	call(settype, "type", "ebcdic", 0);
295*7c478bd9Sstevel@tonic-gate }
296*7c478bd9Sstevel@tonic-gate 
297*7c478bd9Sstevel@tonic-gate /*
298*7c478bd9Sstevel@tonic-gate  * Set file transfer mode.
299*7c478bd9Sstevel@tonic-gate  */
300*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
301*7c478bd9Sstevel@tonic-gate void
302*7c478bd9Sstevel@tonic-gate setmode(int argc, char *argv[])
303*7c478bd9Sstevel@tonic-gate {
304*7c478bd9Sstevel@tonic-gate 	(void) printf("We only support %s mode, sorry.\n", modename);
305*7c478bd9Sstevel@tonic-gate 	code = -1;
306*7c478bd9Sstevel@tonic-gate }
307*7c478bd9Sstevel@tonic-gate 
308*7c478bd9Sstevel@tonic-gate /*
309*7c478bd9Sstevel@tonic-gate  * Set file transfer format.
310*7c478bd9Sstevel@tonic-gate  */
311*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
312*7c478bd9Sstevel@tonic-gate void
313*7c478bd9Sstevel@tonic-gate setform(int argc, char *argv[])
314*7c478bd9Sstevel@tonic-gate {
315*7c478bd9Sstevel@tonic-gate 	(void) printf("We only support %s format, sorry.\n", formname);
316*7c478bd9Sstevel@tonic-gate 	code = -1;
317*7c478bd9Sstevel@tonic-gate }
318*7c478bd9Sstevel@tonic-gate 
319*7c478bd9Sstevel@tonic-gate /*
320*7c478bd9Sstevel@tonic-gate  * Set file transfer structure.
321*7c478bd9Sstevel@tonic-gate  */
322*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
323*7c478bd9Sstevel@tonic-gate void
324*7c478bd9Sstevel@tonic-gate setstruct(int argc, char *argv[])
325*7c478bd9Sstevel@tonic-gate {
326*7c478bd9Sstevel@tonic-gate 
327*7c478bd9Sstevel@tonic-gate 	(void) printf("We only support %s structure, sorry.\n", structname);
328*7c478bd9Sstevel@tonic-gate 	code = -1;
329*7c478bd9Sstevel@tonic-gate }
330*7c478bd9Sstevel@tonic-gate 
331*7c478bd9Sstevel@tonic-gate /*
332*7c478bd9Sstevel@tonic-gate  * Send a single file.
333*7c478bd9Sstevel@tonic-gate  */
334*7c478bd9Sstevel@tonic-gate void
335*7c478bd9Sstevel@tonic-gate put(int argc, char *argv[])
336*7c478bd9Sstevel@tonic-gate {
337*7c478bd9Sstevel@tonic-gate 	char *cmd;
338*7c478bd9Sstevel@tonic-gate 	int loc = 0;
339*7c478bd9Sstevel@tonic-gate 	char *oldargv1;
340*7c478bd9Sstevel@tonic-gate 
341*7c478bd9Sstevel@tonic-gate 	if (argc == 2) {
342*7c478bd9Sstevel@tonic-gate 		argc++;
343*7c478bd9Sstevel@tonic-gate 		argv[2] = argv[1];
344*7c478bd9Sstevel@tonic-gate 		loc++;
345*7c478bd9Sstevel@tonic-gate 	}
346*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
347*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "local-file") == -1) {
348*7c478bd9Sstevel@tonic-gate 			code = -1;
349*7c478bd9Sstevel@tonic-gate 			return;
350*7c478bd9Sstevel@tonic-gate 		}
351*7c478bd9Sstevel@tonic-gate 		makeargv();
352*7c478bd9Sstevel@tonic-gate 		argc = margc;
353*7c478bd9Sstevel@tonic-gate 		argv = margv;
354*7c478bd9Sstevel@tonic-gate 	}
355*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
356*7c478bd9Sstevel@tonic-gate usage:
357*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s local-file remote-file\n", argv[0]);
358*7c478bd9Sstevel@tonic-gate 		code = -1;
359*7c478bd9Sstevel@tonic-gate 		return;
360*7c478bd9Sstevel@tonic-gate 	}
361*7c478bd9Sstevel@tonic-gate 	if (argc < 3) {
362*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "remote-file") == -1) {
363*7c478bd9Sstevel@tonic-gate 			code = -1;
364*7c478bd9Sstevel@tonic-gate 			return;
365*7c478bd9Sstevel@tonic-gate 		}
366*7c478bd9Sstevel@tonic-gate 		makeargv();
367*7c478bd9Sstevel@tonic-gate 		argc = margc;
368*7c478bd9Sstevel@tonic-gate 		argv = margv;
369*7c478bd9Sstevel@tonic-gate 	}
370*7c478bd9Sstevel@tonic-gate 	if (argc < 3)
371*7c478bd9Sstevel@tonic-gate 		goto usage;
372*7c478bd9Sstevel@tonic-gate 	oldargv1 = argv[1];
373*7c478bd9Sstevel@tonic-gate 	if (!globulize(&argv[1])) {
374*7c478bd9Sstevel@tonic-gate 		code = -1;
375*7c478bd9Sstevel@tonic-gate 		return;
376*7c478bd9Sstevel@tonic-gate 	}
377*7c478bd9Sstevel@tonic-gate 	/*
378*7c478bd9Sstevel@tonic-gate 	 * If "globulize" modifies argv[1], and argv[2] is a copy of
379*7c478bd9Sstevel@tonic-gate 	 * the old argv[1], make it a copy of the new argv[1].
380*7c478bd9Sstevel@tonic-gate 	 */
381*7c478bd9Sstevel@tonic-gate 	if (argv[1] != oldargv1 && argv[2] == oldargv1) {
382*7c478bd9Sstevel@tonic-gate 		argv[2] = argv[1];
383*7c478bd9Sstevel@tonic-gate 	}
384*7c478bd9Sstevel@tonic-gate 	cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR");
385*7c478bd9Sstevel@tonic-gate 	if (loc && ntflag) {
386*7c478bd9Sstevel@tonic-gate 		argv[2] = dotrans(argv[2]);
387*7c478bd9Sstevel@tonic-gate 	}
388*7c478bd9Sstevel@tonic-gate 	if (loc && mapflag) {
389*7c478bd9Sstevel@tonic-gate 		argv[2] = domap(argv[2]);
390*7c478bd9Sstevel@tonic-gate 	}
391*7c478bd9Sstevel@tonic-gate 	sendrequest(cmd, argv[1], argv[2], 1);
392*7c478bd9Sstevel@tonic-gate }
393*7c478bd9Sstevel@tonic-gate 
394*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
395*7c478bd9Sstevel@tonic-gate static void
396*7c478bd9Sstevel@tonic-gate mabort(int sig)
397*7c478bd9Sstevel@tonic-gate {
398*7c478bd9Sstevel@tonic-gate 	int ointer;
399*7c478bd9Sstevel@tonic-gate 
400*7c478bd9Sstevel@tonic-gate 	(void) printf("\n");
401*7c478bd9Sstevel@tonic-gate 	(void) fflush(stdout);
402*7c478bd9Sstevel@tonic-gate 	if (mflag && fromatty) {
403*7c478bd9Sstevel@tonic-gate 		ointer = interactive;
404*7c478bd9Sstevel@tonic-gate 		interactive = 1;
405*7c478bd9Sstevel@tonic-gate 		if (confirm("Continue with", mname)) {
406*7c478bd9Sstevel@tonic-gate 			interactive = ointer;
407*7c478bd9Sstevel@tonic-gate 			longjmp(jabort, 0);
408*7c478bd9Sstevel@tonic-gate 		}
409*7c478bd9Sstevel@tonic-gate 		interactive = ointer;
410*7c478bd9Sstevel@tonic-gate 	}
411*7c478bd9Sstevel@tonic-gate 	mflag = 0;
412*7c478bd9Sstevel@tonic-gate 	longjmp(jabort, 0);
413*7c478bd9Sstevel@tonic-gate }
414*7c478bd9Sstevel@tonic-gate 
415*7c478bd9Sstevel@tonic-gate /*
416*7c478bd9Sstevel@tonic-gate  * Send multiple files.
417*7c478bd9Sstevel@tonic-gate  */
418*7c478bd9Sstevel@tonic-gate void
419*7c478bd9Sstevel@tonic-gate mput(int argc, char *argv[])
420*7c478bd9Sstevel@tonic-gate {
421*7c478bd9Sstevel@tonic-gate 	int i;
422*7c478bd9Sstevel@tonic-gate 	int ointer;
423*7c478bd9Sstevel@tonic-gate 	void (*oldintr)();
424*7c478bd9Sstevel@tonic-gate 	char *tp;
425*7c478bd9Sstevel@tonic-gate 	int	len;
426*7c478bd9Sstevel@tonic-gate 
427*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
428*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "local-files") == -1) {
429*7c478bd9Sstevel@tonic-gate 			code = -1;
430*7c478bd9Sstevel@tonic-gate 			return;
431*7c478bd9Sstevel@tonic-gate 		}
432*7c478bd9Sstevel@tonic-gate 		makeargv();
433*7c478bd9Sstevel@tonic-gate 		argc = margc;
434*7c478bd9Sstevel@tonic-gate 		argv = margv;
435*7c478bd9Sstevel@tonic-gate 	}
436*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
437*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s local-files\n", argv[0]);
438*7c478bd9Sstevel@tonic-gate 		code = -1;
439*7c478bd9Sstevel@tonic-gate 		return;
440*7c478bd9Sstevel@tonic-gate 	}
441*7c478bd9Sstevel@tonic-gate 	mname = argv[0];
442*7c478bd9Sstevel@tonic-gate 	mflag = 1;
443*7c478bd9Sstevel@tonic-gate 	oldintr = signal(SIGINT, mabort);
444*7c478bd9Sstevel@tonic-gate 	(void) setjmp(jabort);
445*7c478bd9Sstevel@tonic-gate 	if (proxy) {
446*7c478bd9Sstevel@tonic-gate 		char *cp, *tp2, tmpbuf[MAXPATHLEN];
447*7c478bd9Sstevel@tonic-gate 
448*7c478bd9Sstevel@tonic-gate 		while ((cp = remglob(argv, 0)) != NULL) {
449*7c478bd9Sstevel@tonic-gate 			if (*cp == 0) {
450*7c478bd9Sstevel@tonic-gate 				mflag = 0;
451*7c478bd9Sstevel@tonic-gate 				continue;
452*7c478bd9Sstevel@tonic-gate 			}
453*7c478bd9Sstevel@tonic-gate 			if (mflag && confirm(argv[0], cp)) {
454*7c478bd9Sstevel@tonic-gate 				tp = cp;
455*7c478bd9Sstevel@tonic-gate 				if (mcase) {
456*7c478bd9Sstevel@tonic-gate 					while (*tp) {
457*7c478bd9Sstevel@tonic-gate 						if ((len =
458*7c478bd9Sstevel@tonic-gate 						    mblen(tp, MB_CUR_MAX)) <= 0)
459*7c478bd9Sstevel@tonic-gate 							len = 1;
460*7c478bd9Sstevel@tonic-gate 						if (islower(*tp))
461*7c478bd9Sstevel@tonic-gate 							break;
462*7c478bd9Sstevel@tonic-gate 						tp += len;
463*7c478bd9Sstevel@tonic-gate 					}
464*7c478bd9Sstevel@tonic-gate 					if (!*tp) {
465*7c478bd9Sstevel@tonic-gate 						tp = cp;
466*7c478bd9Sstevel@tonic-gate 						tp2 = tmpbuf;
467*7c478bd9Sstevel@tonic-gate 						while (*tp) {
468*7c478bd9Sstevel@tonic-gate 							if ((len = mblen(tp,
469*7c478bd9Sstevel@tonic-gate 							    MB_CUR_MAX)) <= 0)
470*7c478bd9Sstevel@tonic-gate 								len = 1;
471*7c478bd9Sstevel@tonic-gate 							memcpy(tp2, tp, len);
472*7c478bd9Sstevel@tonic-gate 							if (isupper(*tp2)) {
473*7c478bd9Sstevel@tonic-gate 								*tp2 = 'a' +
474*7c478bd9Sstevel@tonic-gate 								    *tp2 - 'A';
475*7c478bd9Sstevel@tonic-gate 							}
476*7c478bd9Sstevel@tonic-gate 							tp += len;
477*7c478bd9Sstevel@tonic-gate 							tp2 += len;
478*7c478bd9Sstevel@tonic-gate 						}
479*7c478bd9Sstevel@tonic-gate 						*tp2 = 0;
480*7c478bd9Sstevel@tonic-gate 						tp = tmpbuf;
481*7c478bd9Sstevel@tonic-gate 					}
482*7c478bd9Sstevel@tonic-gate 				}
483*7c478bd9Sstevel@tonic-gate 				if (ntflag) {
484*7c478bd9Sstevel@tonic-gate 					tp = dotrans(tp);
485*7c478bd9Sstevel@tonic-gate 				}
486*7c478bd9Sstevel@tonic-gate 				if (mapflag) {
487*7c478bd9Sstevel@tonic-gate 					tp = domap(tp);
488*7c478bd9Sstevel@tonic-gate 				}
489*7c478bd9Sstevel@tonic-gate 				sendrequest((sunique) ? "STOU" : "STOR",
490*7c478bd9Sstevel@tonic-gate 				    cp, tp, 0);
491*7c478bd9Sstevel@tonic-gate 				if (!mflag && fromatty) {
492*7c478bd9Sstevel@tonic-gate 					ointer = interactive;
493*7c478bd9Sstevel@tonic-gate 					interactive = 1;
494*7c478bd9Sstevel@tonic-gate 					if (confirm("Continue with", "mput")) {
495*7c478bd9Sstevel@tonic-gate 						mflag++;
496*7c478bd9Sstevel@tonic-gate 					}
497*7c478bd9Sstevel@tonic-gate 					interactive = ointer;
498*7c478bd9Sstevel@tonic-gate 				}
499*7c478bd9Sstevel@tonic-gate 			}
500*7c478bd9Sstevel@tonic-gate 		}
501*7c478bd9Sstevel@tonic-gate 		(void) signal(SIGINT, oldintr);
502*7c478bd9Sstevel@tonic-gate 		mflag = 0;
503*7c478bd9Sstevel@tonic-gate 		return;
504*7c478bd9Sstevel@tonic-gate 	}
505*7c478bd9Sstevel@tonic-gate 	for (i = 1; i < argc; i++) {
506*7c478bd9Sstevel@tonic-gate 		char **cpp, **gargs;
507*7c478bd9Sstevel@tonic-gate 
508*7c478bd9Sstevel@tonic-gate 		if (!doglob) {
509*7c478bd9Sstevel@tonic-gate 			if (mflag && confirm(argv[0], argv[i])) {
510*7c478bd9Sstevel@tonic-gate 				tp = (ntflag) ? dotrans(argv[i]) : argv[i];
511*7c478bd9Sstevel@tonic-gate 				tp = (mapflag) ? domap(tp) : tp;
512*7c478bd9Sstevel@tonic-gate 				sendrequest((sunique) ? "STOU" : "STOR",
513*7c478bd9Sstevel@tonic-gate 				    argv[i], tp, 1);
514*7c478bd9Sstevel@tonic-gate 				if (!mflag && fromatty) {
515*7c478bd9Sstevel@tonic-gate 					ointer = interactive;
516*7c478bd9Sstevel@tonic-gate 					interactive = 1;
517*7c478bd9Sstevel@tonic-gate 					if (confirm("Continue with", "mput")) {
518*7c478bd9Sstevel@tonic-gate 						mflag++;
519*7c478bd9Sstevel@tonic-gate 					}
520*7c478bd9Sstevel@tonic-gate 					interactive = ointer;
521*7c478bd9Sstevel@tonic-gate 				}
522*7c478bd9Sstevel@tonic-gate 			}
523*7c478bd9Sstevel@tonic-gate 			continue;
524*7c478bd9Sstevel@tonic-gate 		}
525*7c478bd9Sstevel@tonic-gate 		gargs = glob(argv[i]);
526*7c478bd9Sstevel@tonic-gate 		if (globerr != NULL) {
527*7c478bd9Sstevel@tonic-gate 			(void) printf("%s\n", globerr);
528*7c478bd9Sstevel@tonic-gate 			if (gargs)
529*7c478bd9Sstevel@tonic-gate 				blkfree(gargs);
530*7c478bd9Sstevel@tonic-gate 			continue;
531*7c478bd9Sstevel@tonic-gate 		}
532*7c478bd9Sstevel@tonic-gate 		for (cpp = gargs; cpp && *cpp != NULL; cpp++) {
533*7c478bd9Sstevel@tonic-gate 			if (mflag && confirm(argv[0], *cpp)) {
534*7c478bd9Sstevel@tonic-gate 				tp = (ntflag) ? dotrans(*cpp) : *cpp;
535*7c478bd9Sstevel@tonic-gate 				tp = (mapflag) ? domap(tp) : tp;
536*7c478bd9Sstevel@tonic-gate 				sendrequest((sunique) ? "STOU" : "STOR",
537*7c478bd9Sstevel@tonic-gate 				    *cpp, tp, 0);
538*7c478bd9Sstevel@tonic-gate 				if (!mflag && fromatty) {
539*7c478bd9Sstevel@tonic-gate 					ointer = interactive;
540*7c478bd9Sstevel@tonic-gate 					interactive = 1;
541*7c478bd9Sstevel@tonic-gate 					if (confirm("Continue with", "mput")) {
542*7c478bd9Sstevel@tonic-gate 						mflag++;
543*7c478bd9Sstevel@tonic-gate 					}
544*7c478bd9Sstevel@tonic-gate 					interactive = ointer;
545*7c478bd9Sstevel@tonic-gate 				}
546*7c478bd9Sstevel@tonic-gate 			}
547*7c478bd9Sstevel@tonic-gate 		}
548*7c478bd9Sstevel@tonic-gate 		if (gargs != NULL)
549*7c478bd9Sstevel@tonic-gate 			blkfree(gargs);
550*7c478bd9Sstevel@tonic-gate 	}
551*7c478bd9Sstevel@tonic-gate 	(void) signal(SIGINT, oldintr);
552*7c478bd9Sstevel@tonic-gate 	mflag = 0;
553*7c478bd9Sstevel@tonic-gate }
554*7c478bd9Sstevel@tonic-gate 
555*7c478bd9Sstevel@tonic-gate /*
556*7c478bd9Sstevel@tonic-gate  * Restart transfer at a specific offset.
557*7c478bd9Sstevel@tonic-gate  */
558*7c478bd9Sstevel@tonic-gate void
559*7c478bd9Sstevel@tonic-gate restart(int argc, char *argv[])
560*7c478bd9Sstevel@tonic-gate {
561*7c478bd9Sstevel@tonic-gate 	off_t orestart_point = restart_point;
562*7c478bd9Sstevel@tonic-gate 
563*7c478bd9Sstevel@tonic-gate 	if (argc > 2) {
564*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s [marker]\n", argv[0]);
565*7c478bd9Sstevel@tonic-gate 		code = -1;
566*7c478bd9Sstevel@tonic-gate 		return;
567*7c478bd9Sstevel@tonic-gate 	}
568*7c478bd9Sstevel@tonic-gate 	if (argc == 2) {
569*7c478bd9Sstevel@tonic-gate 		longlong_t rp;
570*7c478bd9Sstevel@tonic-gate 		char *endp;
571*7c478bd9Sstevel@tonic-gate 
572*7c478bd9Sstevel@tonic-gate 		errno = 0;
573*7c478bd9Sstevel@tonic-gate 		rp = strtoll(argv[1], &endp, 10);
574*7c478bd9Sstevel@tonic-gate 		if (errno || rp < 0 || *endp != '\0')
575*7c478bd9Sstevel@tonic-gate 			(void) printf("%s: Invalid offset `%s'\n",
576*7c478bd9Sstevel@tonic-gate 				argv[0], argv[1]);
577*7c478bd9Sstevel@tonic-gate 		else
578*7c478bd9Sstevel@tonic-gate 			restart_point = rp;
579*7c478bd9Sstevel@tonic-gate 	}
580*7c478bd9Sstevel@tonic-gate 	if (restart_point == 0) {
581*7c478bd9Sstevel@tonic-gate 		if (orestart_point == 0)
582*7c478bd9Sstevel@tonic-gate 			(void) printf("No restart marker defined\n");
583*7c478bd9Sstevel@tonic-gate 		else
584*7c478bd9Sstevel@tonic-gate 			(void) printf("Restart marker cleared\n");
585*7c478bd9Sstevel@tonic-gate 	} else
586*7c478bd9Sstevel@tonic-gate 		(void) printf(
587*7c478bd9Sstevel@tonic-gate 			"Restarting at %lld for next get, put or append\n",
588*7c478bd9Sstevel@tonic-gate 			(longlong_t)restart_point);
589*7c478bd9Sstevel@tonic-gate }
590*7c478bd9Sstevel@tonic-gate 
591*7c478bd9Sstevel@tonic-gate void
592*7c478bd9Sstevel@tonic-gate reget(int argc, char *argv[])
593*7c478bd9Sstevel@tonic-gate {
594*7c478bd9Sstevel@tonic-gate 	getit(argc, argv, 1, "r+w");
595*7c478bd9Sstevel@tonic-gate }
596*7c478bd9Sstevel@tonic-gate 
597*7c478bd9Sstevel@tonic-gate void
598*7c478bd9Sstevel@tonic-gate get(int argc, char *argv[])
599*7c478bd9Sstevel@tonic-gate {
600*7c478bd9Sstevel@tonic-gate 	getit(argc, argv, 0, restart_point ? "r+w" : "w");
601*7c478bd9Sstevel@tonic-gate }
602*7c478bd9Sstevel@tonic-gate 
603*7c478bd9Sstevel@tonic-gate /*
604*7c478bd9Sstevel@tonic-gate  * Receive one file.
605*7c478bd9Sstevel@tonic-gate  */
606*7c478bd9Sstevel@tonic-gate static void
607*7c478bd9Sstevel@tonic-gate getit(int argc, char *argv[], int restartit, char *mode)
608*7c478bd9Sstevel@tonic-gate {
609*7c478bd9Sstevel@tonic-gate 	int loc = 0;
610*7c478bd9Sstevel@tonic-gate 	int len;
611*7c478bd9Sstevel@tonic-gate 	int allowpipe = 1;
612*7c478bd9Sstevel@tonic-gate 
613*7c478bd9Sstevel@tonic-gate 	if (argc == 2) {
614*7c478bd9Sstevel@tonic-gate 		argc++;
615*7c478bd9Sstevel@tonic-gate 		argv[2] = argv[1];
616*7c478bd9Sstevel@tonic-gate 		/* Only permit !file if two arguments. */
617*7c478bd9Sstevel@tonic-gate 		allowpipe = 0;
618*7c478bd9Sstevel@tonic-gate 		loc++;
619*7c478bd9Sstevel@tonic-gate 	}
620*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
621*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "remote-file") == -1) {
622*7c478bd9Sstevel@tonic-gate 			code = -1;
623*7c478bd9Sstevel@tonic-gate 			return;
624*7c478bd9Sstevel@tonic-gate 		}
625*7c478bd9Sstevel@tonic-gate 		makeargv();
626*7c478bd9Sstevel@tonic-gate 		argc = margc;
627*7c478bd9Sstevel@tonic-gate 		argv = margv;
628*7c478bd9Sstevel@tonic-gate 	}
629*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
630*7c478bd9Sstevel@tonic-gate usage:
631*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s remote-file [ local-file ]\n",
632*7c478bd9Sstevel@tonic-gate 			argv[0]);
633*7c478bd9Sstevel@tonic-gate 		code = -1;
634*7c478bd9Sstevel@tonic-gate 		return;
635*7c478bd9Sstevel@tonic-gate 	}
636*7c478bd9Sstevel@tonic-gate 	if (argc < 3) {
637*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "local-file") == -1) {
638*7c478bd9Sstevel@tonic-gate 			code = -1;
639*7c478bd9Sstevel@tonic-gate 			return;
640*7c478bd9Sstevel@tonic-gate 		}
641*7c478bd9Sstevel@tonic-gate 		makeargv();
642*7c478bd9Sstevel@tonic-gate 		argc = margc;
643*7c478bd9Sstevel@tonic-gate 		argv = margv;
644*7c478bd9Sstevel@tonic-gate 	}
645*7c478bd9Sstevel@tonic-gate 	if (argc < 3)
646*7c478bd9Sstevel@tonic-gate 		goto usage;
647*7c478bd9Sstevel@tonic-gate 	if (!globulize(&argv[2])) {
648*7c478bd9Sstevel@tonic-gate 		code = -1;
649*7c478bd9Sstevel@tonic-gate 		return;
650*7c478bd9Sstevel@tonic-gate 	}
651*7c478bd9Sstevel@tonic-gate 	if (loc && mcase) {
652*7c478bd9Sstevel@tonic-gate 		char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN];
653*7c478bd9Sstevel@tonic-gate 
654*7c478bd9Sstevel@tonic-gate 		while (*tp) {
655*7c478bd9Sstevel@tonic-gate 			if ((len = mblen(tp, MB_CUR_MAX)) <= 0)
656*7c478bd9Sstevel@tonic-gate 				len = 1;
657*7c478bd9Sstevel@tonic-gate 			if (islower(*tp))
658*7c478bd9Sstevel@tonic-gate 				break;
659*7c478bd9Sstevel@tonic-gate 			tp += len;
660*7c478bd9Sstevel@tonic-gate 		}
661*7c478bd9Sstevel@tonic-gate 		if (!*tp) {
662*7c478bd9Sstevel@tonic-gate 			tp = argv[2];
663*7c478bd9Sstevel@tonic-gate 			tp2 = tmpbuf;
664*7c478bd9Sstevel@tonic-gate 			while (*tp) {
665*7c478bd9Sstevel@tonic-gate 				if ((len = mblen(tp, MB_CUR_MAX)) <= 0)
666*7c478bd9Sstevel@tonic-gate 					len = 1;
667*7c478bd9Sstevel@tonic-gate 				memcpy(tp2, tp, len);
668*7c478bd9Sstevel@tonic-gate 				if (isupper(*tp2))
669*7c478bd9Sstevel@tonic-gate 					*tp2 = 'a' + *tp2 - 'A';
670*7c478bd9Sstevel@tonic-gate 				tp += len;
671*7c478bd9Sstevel@tonic-gate 				tp2 += len;
672*7c478bd9Sstevel@tonic-gate 			}
673*7c478bd9Sstevel@tonic-gate 			*tp2 = 0;
674*7c478bd9Sstevel@tonic-gate 			argv[2] = tmpbuf;
675*7c478bd9Sstevel@tonic-gate 		}
676*7c478bd9Sstevel@tonic-gate 	}
677*7c478bd9Sstevel@tonic-gate 	if (loc && ntflag) {
678*7c478bd9Sstevel@tonic-gate 		argv[2] = dotrans(argv[2]);
679*7c478bd9Sstevel@tonic-gate 	}
680*7c478bd9Sstevel@tonic-gate 	if (loc && mapflag) {
681*7c478bd9Sstevel@tonic-gate 		argv[2] = domap(argv[2]);
682*7c478bd9Sstevel@tonic-gate 	}
683*7c478bd9Sstevel@tonic-gate 	if (restartit) {
684*7c478bd9Sstevel@tonic-gate 		struct stat stbuf;
685*7c478bd9Sstevel@tonic-gate 
686*7c478bd9Sstevel@tonic-gate 		if (stat(argv[2], &stbuf) < 0) {
687*7c478bd9Sstevel@tonic-gate 			perror(argv[2]);
688*7c478bd9Sstevel@tonic-gate 			code = -1;
689*7c478bd9Sstevel@tonic-gate 			return;
690*7c478bd9Sstevel@tonic-gate 		}
691*7c478bd9Sstevel@tonic-gate 		restart_point = stbuf.st_size;
692*7c478bd9Sstevel@tonic-gate 	}
693*7c478bd9Sstevel@tonic-gate 	recvrequest("RETR", argv[2], argv[1], mode, allowpipe);
694*7c478bd9Sstevel@tonic-gate 	restart_point = 0;
695*7c478bd9Sstevel@tonic-gate }
696*7c478bd9Sstevel@tonic-gate 
697*7c478bd9Sstevel@tonic-gate /*
698*7c478bd9Sstevel@tonic-gate  * Get multiple files.
699*7c478bd9Sstevel@tonic-gate  */
700*7c478bd9Sstevel@tonic-gate void
701*7c478bd9Sstevel@tonic-gate mget(int argc, char *argv[])
702*7c478bd9Sstevel@tonic-gate {
703*7c478bd9Sstevel@tonic-gate 	char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN];
704*7c478bd9Sstevel@tonic-gate 	int ointer;
705*7c478bd9Sstevel@tonic-gate 	void (*oldintr)();
706*7c478bd9Sstevel@tonic-gate 	int need_convert;
707*7c478bd9Sstevel@tonic-gate 	int	len;
708*7c478bd9Sstevel@tonic-gate 
709*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
710*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "remote-files") < 0) {
711*7c478bd9Sstevel@tonic-gate 			code = -1;
712*7c478bd9Sstevel@tonic-gate 			return;
713*7c478bd9Sstevel@tonic-gate 		}
714*7c478bd9Sstevel@tonic-gate 		makeargv();
715*7c478bd9Sstevel@tonic-gate 		argc = margc;
716*7c478bd9Sstevel@tonic-gate 		argv = margv;
717*7c478bd9Sstevel@tonic-gate 	}
718*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
719*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s remote-files\n", argv[0]);
720*7c478bd9Sstevel@tonic-gate 		code = -1;
721*7c478bd9Sstevel@tonic-gate 		return;
722*7c478bd9Sstevel@tonic-gate 	}
723*7c478bd9Sstevel@tonic-gate 	mname = argv[0];
724*7c478bd9Sstevel@tonic-gate 	mflag = 1;
725*7c478bd9Sstevel@tonic-gate 	oldintr = signal(SIGINT, mabort);
726*7c478bd9Sstevel@tonic-gate 	(void) setjmp(jabort);
727*7c478bd9Sstevel@tonic-gate 	while ((cp = remglob(argv, proxy)) != NULL) {
728*7c478bd9Sstevel@tonic-gate 		if (*cp == '\0') {
729*7c478bd9Sstevel@tonic-gate 			mflag = 0;
730*7c478bd9Sstevel@tonic-gate 			continue;
731*7c478bd9Sstevel@tonic-gate 		}
732*7c478bd9Sstevel@tonic-gate 		if (mflag && confirm(argv[0], cp)) {
733*7c478bd9Sstevel@tonic-gate 			strcpy(tmpbuf, cp);
734*7c478bd9Sstevel@tonic-gate 			tp =  tmpbuf;
735*7c478bd9Sstevel@tonic-gate 			need_convert = 1;
736*7c478bd9Sstevel@tonic-gate 			if (mcase) {
737*7c478bd9Sstevel@tonic-gate 				tp2 = tp;
738*7c478bd9Sstevel@tonic-gate 				while (*tp2 && need_convert) {
739*7c478bd9Sstevel@tonic-gate 				/* Need any case convert? */
740*7c478bd9Sstevel@tonic-gate 					if (islower(*tp2))
741*7c478bd9Sstevel@tonic-gate 						need_convert = 0;
742*7c478bd9Sstevel@tonic-gate 					if ((len = mblen(tp2, MB_CUR_MAX)) <= 0)
743*7c478bd9Sstevel@tonic-gate 						len = 1;
744*7c478bd9Sstevel@tonic-gate 					tp2 += len;
745*7c478bd9Sstevel@tonic-gate 				}
746*7c478bd9Sstevel@tonic-gate 				tp2 = tp;
747*7c478bd9Sstevel@tonic-gate 				while (need_convert && *tp2) {
748*7c478bd9Sstevel@tonic-gate 				/* Convert to lower case */
749*7c478bd9Sstevel@tonic-gate 					if (isupper(*tp2))
750*7c478bd9Sstevel@tonic-gate 						*tp2 = tolower(*tp2);
751*7c478bd9Sstevel@tonic-gate 					if ((len = mblen(tp2, MB_CUR_MAX)) <= 0)
752*7c478bd9Sstevel@tonic-gate 						len = 1;
753*7c478bd9Sstevel@tonic-gate 					tp2 += len;
754*7c478bd9Sstevel@tonic-gate 				}
755*7c478bd9Sstevel@tonic-gate 			}
756*7c478bd9Sstevel@tonic-gate 
757*7c478bd9Sstevel@tonic-gate 			if (ntflag) {
758*7c478bd9Sstevel@tonic-gate 				tp = dotrans(tp);
759*7c478bd9Sstevel@tonic-gate 			}
760*7c478bd9Sstevel@tonic-gate 			if (mapflag) {
761*7c478bd9Sstevel@tonic-gate 				tp = domap(tp);
762*7c478bd9Sstevel@tonic-gate 			}
763*7c478bd9Sstevel@tonic-gate 			recvrequest("RETR", tp, cp, "w", 0);
764*7c478bd9Sstevel@tonic-gate 			restart_point = 0;
765*7c478bd9Sstevel@tonic-gate 			if (!mflag && fromatty) {
766*7c478bd9Sstevel@tonic-gate 				ointer = interactive;
767*7c478bd9Sstevel@tonic-gate 				interactive = 1;
768*7c478bd9Sstevel@tonic-gate 				if (confirm("Continue with", "mget")) {
769*7c478bd9Sstevel@tonic-gate 					mflag++;
770*7c478bd9Sstevel@tonic-gate 				}
771*7c478bd9Sstevel@tonic-gate 				interactive = ointer;
772*7c478bd9Sstevel@tonic-gate 			}
773*7c478bd9Sstevel@tonic-gate 		}
774*7c478bd9Sstevel@tonic-gate 	}
775*7c478bd9Sstevel@tonic-gate 	(void) signal(SIGINT, oldintr);
776*7c478bd9Sstevel@tonic-gate 	mflag = 0;
777*7c478bd9Sstevel@tonic-gate }
778*7c478bd9Sstevel@tonic-gate 
779*7c478bd9Sstevel@tonic-gate static char *
780*7c478bd9Sstevel@tonic-gate remglob(char *argv[], int doswitch)
781*7c478bd9Sstevel@tonic-gate {
782*7c478bd9Sstevel@tonic-gate 	static char buf[MAXPATHLEN];
783*7c478bd9Sstevel@tonic-gate 	static char **args;
784*7c478bd9Sstevel@tonic-gate 	int oldverbose, oldhash;
785*7c478bd9Sstevel@tonic-gate 	char *cp;
786*7c478bd9Sstevel@tonic-gate 
787*7c478bd9Sstevel@tonic-gate 	if (!mflag) {
788*7c478bd9Sstevel@tonic-gate 		if (!doglob) {
789*7c478bd9Sstevel@tonic-gate 			args = NULL;
790*7c478bd9Sstevel@tonic-gate 		} else {
791*7c478bd9Sstevel@tonic-gate 			if (tmp_nlst != NULL) {
792*7c478bd9Sstevel@tonic-gate 				(void) fclose(tmp_nlst);
793*7c478bd9Sstevel@tonic-gate 				tmp_nlst = NULL;
794*7c478bd9Sstevel@tonic-gate 			}
795*7c478bd9Sstevel@tonic-gate 		}
796*7c478bd9Sstevel@tonic-gate 		return (NULL);
797*7c478bd9Sstevel@tonic-gate 	}
798*7c478bd9Sstevel@tonic-gate 	if (!doglob) {
799*7c478bd9Sstevel@tonic-gate 		if (args == NULL)
800*7c478bd9Sstevel@tonic-gate 			args = argv;
801*7c478bd9Sstevel@tonic-gate 		if ((cp = *++args) == NULL)
802*7c478bd9Sstevel@tonic-gate 			args = NULL;
803*7c478bd9Sstevel@tonic-gate 		return (cp);
804*7c478bd9Sstevel@tonic-gate 	}
805*7c478bd9Sstevel@tonic-gate 	if (tmp_nlst == NULL) {
806*7c478bd9Sstevel@tonic-gate 		if ((tmp_nlst = tmpfile()) == NULL) {
807*7c478bd9Sstevel@tonic-gate 			(void) printf("%s\n", strerror(errno));
808*7c478bd9Sstevel@tonic-gate 			return (NULL);
809*7c478bd9Sstevel@tonic-gate 		}
810*7c478bd9Sstevel@tonic-gate 		oldverbose = verbose, verbose = 0;
811*7c478bd9Sstevel@tonic-gate 		oldhash = hash, hash = 0;
812*7c478bd9Sstevel@tonic-gate 		if (doswitch) {
813*7c478bd9Sstevel@tonic-gate 			pswitch(!proxy);
814*7c478bd9Sstevel@tonic-gate 		}
815*7c478bd9Sstevel@tonic-gate 		for (; *++argv != NULL; )
816*7c478bd9Sstevel@tonic-gate 			recvrequest("NLST", NULL, *argv, "", 0);
817*7c478bd9Sstevel@tonic-gate 		rewind(tmp_nlst);
818*7c478bd9Sstevel@tonic-gate 		if (doswitch) {
819*7c478bd9Sstevel@tonic-gate 			pswitch(!proxy);
820*7c478bd9Sstevel@tonic-gate 		}
821*7c478bd9Sstevel@tonic-gate 		verbose = oldverbose; hash = oldhash;
822*7c478bd9Sstevel@tonic-gate 	}
823*7c478bd9Sstevel@tonic-gate 	reset_timer();
824*7c478bd9Sstevel@tonic-gate 	if (fgets(buf, sizeof (buf), tmp_nlst) == NULL) {
825*7c478bd9Sstevel@tonic-gate 		(void) fclose(tmp_nlst), tmp_nlst = NULL;
826*7c478bd9Sstevel@tonic-gate 		return (NULL);
827*7c478bd9Sstevel@tonic-gate 	}
828*7c478bd9Sstevel@tonic-gate 	if ((cp = index(buf, '\n')) != NULL)
829*7c478bd9Sstevel@tonic-gate 		*cp = '\0';
830*7c478bd9Sstevel@tonic-gate 	return (buf);
831*7c478bd9Sstevel@tonic-gate }
832*7c478bd9Sstevel@tonic-gate 
833*7c478bd9Sstevel@tonic-gate static char *
834*7c478bd9Sstevel@tonic-gate onoff(int bool)
835*7c478bd9Sstevel@tonic-gate {
836*7c478bd9Sstevel@tonic-gate 	return (bool ? "on" : "off");
837*7c478bd9Sstevel@tonic-gate }
838*7c478bd9Sstevel@tonic-gate 
839*7c478bd9Sstevel@tonic-gate /*
840*7c478bd9Sstevel@tonic-gate  * Show status.
841*7c478bd9Sstevel@tonic-gate  */
842*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
843*7c478bd9Sstevel@tonic-gate void
844*7c478bd9Sstevel@tonic-gate status(int argc, char *argv[])
845*7c478bd9Sstevel@tonic-gate {
846*7c478bd9Sstevel@tonic-gate 	int i;
847*7c478bd9Sstevel@tonic-gate 	char *levelp;
848*7c478bd9Sstevel@tonic-gate 
849*7c478bd9Sstevel@tonic-gate 	if (connected)
850*7c478bd9Sstevel@tonic-gate 		(void) printf("Connected to %s.\n", hostname);
851*7c478bd9Sstevel@tonic-gate 	else
852*7c478bd9Sstevel@tonic-gate 		(void) printf("Not connected.\n");
853*7c478bd9Sstevel@tonic-gate 	if (!proxy) {
854*7c478bd9Sstevel@tonic-gate 		pswitch(1);
855*7c478bd9Sstevel@tonic-gate 		if (connected) {
856*7c478bd9Sstevel@tonic-gate 			(void) printf("Connected for proxy commands to %s.\n",
857*7c478bd9Sstevel@tonic-gate 			    hostname);
858*7c478bd9Sstevel@tonic-gate 		} else {
859*7c478bd9Sstevel@tonic-gate 			(void) printf("No proxy connection.\n");
860*7c478bd9Sstevel@tonic-gate 		}
861*7c478bd9Sstevel@tonic-gate 		pswitch(0);
862*7c478bd9Sstevel@tonic-gate 	}
863*7c478bd9Sstevel@tonic-gate 
864*7c478bd9Sstevel@tonic-gate 	if (auth_type != AUTHTYPE_NONE)
865*7c478bd9Sstevel@tonic-gate 		(void) printf("Authentication type: %s\n",
866*7c478bd9Sstevel@tonic-gate 			GSS_AUTHTYPE_NAME(auth_type));
867*7c478bd9Sstevel@tonic-gate 	else
868*7c478bd9Sstevel@tonic-gate 		(void) printf("Not authenticated.\n");
869*7c478bd9Sstevel@tonic-gate 	(void) printf("Mechanism: %s\n", mechstr);
870*7c478bd9Sstevel@tonic-gate 	(void) printf("Autoauth: %s; Autologin: %s\n",
871*7c478bd9Sstevel@tonic-gate 		onoff(autoauth), onoff(autologin));
872*7c478bd9Sstevel@tonic-gate 	levelp = getlevel(clevel);
873*7c478bd9Sstevel@tonic-gate 	(void) printf("Control Channel Protection Level: %s\n",
874*7c478bd9Sstevel@tonic-gate 		levelp ? levelp : "<unknown>");
875*7c478bd9Sstevel@tonic-gate 	levelp = getlevel(dlevel);
876*7c478bd9Sstevel@tonic-gate 	(void) printf("Data Channel Protection Level: %s\n",
877*7c478bd9Sstevel@tonic-gate 		levelp ? levelp : "<unknown>");
878*7c478bd9Sstevel@tonic-gate 
879*7c478bd9Sstevel@tonic-gate 	(void) printf("Passive mode: %s.\n", onoff(passivemode));
880*7c478bd9Sstevel@tonic-gate 	(void) printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n",
881*7c478bd9Sstevel@tonic-gate 		modename, typename, formname, structname);
882*7c478bd9Sstevel@tonic-gate 	(void) printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n",
883*7c478bd9Sstevel@tonic-gate 		onoff(verbose), onoff(bell), onoff(interactive),
884*7c478bd9Sstevel@tonic-gate 		onoff(doglob));
885*7c478bd9Sstevel@tonic-gate 	(void) printf("Store unique: %s; Receive unique: %s\n", onoff(sunique),
886*7c478bd9Sstevel@tonic-gate 		onoff(runique));
887*7c478bd9Sstevel@tonic-gate 	(void) printf("Case: %s; CR stripping: %s\n",
888*7c478bd9Sstevel@tonic-gate 		onoff(mcase), onoff(crflag));
889*7c478bd9Sstevel@tonic-gate 	if (ntflag) {
890*7c478bd9Sstevel@tonic-gate 		(void) printf("Ntrans: (in) %s (out) %s\n", ntin, ntout);
891*7c478bd9Sstevel@tonic-gate 	} else {
892*7c478bd9Sstevel@tonic-gate 		(void) printf("Ntrans: off\n");
893*7c478bd9Sstevel@tonic-gate 	}
894*7c478bd9Sstevel@tonic-gate 	if (mapflag) {
895*7c478bd9Sstevel@tonic-gate 		(void) printf("Nmap: (in) %s (out) %s\n", mapin, mapout);
896*7c478bd9Sstevel@tonic-gate 	} else {
897*7c478bd9Sstevel@tonic-gate 		(void) printf("Nmap: off\n");
898*7c478bd9Sstevel@tonic-gate 	}
899*7c478bd9Sstevel@tonic-gate 	(void) printf("Hash mark printing: %s; Use of PORT cmds: %s\n",
900*7c478bd9Sstevel@tonic-gate 		onoff(hash), onoff(sendport));
901*7c478bd9Sstevel@tonic-gate 	if (macnum > 0) {
902*7c478bd9Sstevel@tonic-gate 		(void) printf("Macros:\n");
903*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < macnum; i++) {
904*7c478bd9Sstevel@tonic-gate 			(void) printf("\t%s\n", macros[i].mac_name);
905*7c478bd9Sstevel@tonic-gate 		}
906*7c478bd9Sstevel@tonic-gate 	}
907*7c478bd9Sstevel@tonic-gate 	code = 0;
908*7c478bd9Sstevel@tonic-gate }
909*7c478bd9Sstevel@tonic-gate 
910*7c478bd9Sstevel@tonic-gate /*
911*7c478bd9Sstevel@tonic-gate  * Set beep on cmd completed mode.
912*7c478bd9Sstevel@tonic-gate  */
913*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
914*7c478bd9Sstevel@tonic-gate void
915*7c478bd9Sstevel@tonic-gate setbell(int argc, char *argv[])
916*7c478bd9Sstevel@tonic-gate {
917*7c478bd9Sstevel@tonic-gate 	bell = !bell;
918*7c478bd9Sstevel@tonic-gate 	(void) printf("Bell mode %s.\n", onoff(bell));
919*7c478bd9Sstevel@tonic-gate 	code = bell;
920*7c478bd9Sstevel@tonic-gate }
921*7c478bd9Sstevel@tonic-gate 
922*7c478bd9Sstevel@tonic-gate /*
923*7c478bd9Sstevel@tonic-gate  * Turn on packet tracing.
924*7c478bd9Sstevel@tonic-gate  */
925*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
926*7c478bd9Sstevel@tonic-gate void
927*7c478bd9Sstevel@tonic-gate settrace(int argc, char *argv[])
928*7c478bd9Sstevel@tonic-gate {
929*7c478bd9Sstevel@tonic-gate 	trace = !trace;
930*7c478bd9Sstevel@tonic-gate 	(void) printf("Packet tracing %s.\n", onoff(trace));
931*7c478bd9Sstevel@tonic-gate 	code = trace;
932*7c478bd9Sstevel@tonic-gate }
933*7c478bd9Sstevel@tonic-gate 
934*7c478bd9Sstevel@tonic-gate /*
935*7c478bd9Sstevel@tonic-gate  * Toggle hash mark printing during transfers.
936*7c478bd9Sstevel@tonic-gate  */
937*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
938*7c478bd9Sstevel@tonic-gate void
939*7c478bd9Sstevel@tonic-gate sethash(int argc, char *argv[])
940*7c478bd9Sstevel@tonic-gate {
941*7c478bd9Sstevel@tonic-gate 	hash = !hash;
942*7c478bd9Sstevel@tonic-gate 	(void) printf("Hash mark printing %s", onoff(hash));
943*7c478bd9Sstevel@tonic-gate 	code = hash;
944*7c478bd9Sstevel@tonic-gate 	if (hash)
945*7c478bd9Sstevel@tonic-gate 		(void) printf(" (%d bytes/hash mark)", HASHSIZ);
946*7c478bd9Sstevel@tonic-gate 	(void) printf(".\n");
947*7c478bd9Sstevel@tonic-gate }
948*7c478bd9Sstevel@tonic-gate 
949*7c478bd9Sstevel@tonic-gate /*
950*7c478bd9Sstevel@tonic-gate  * Turn on printing of server echo's.
951*7c478bd9Sstevel@tonic-gate  */
952*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
953*7c478bd9Sstevel@tonic-gate void
954*7c478bd9Sstevel@tonic-gate setverbose(int argc, char *argv[])
955*7c478bd9Sstevel@tonic-gate {
956*7c478bd9Sstevel@tonic-gate 	verbose = !verbose;
957*7c478bd9Sstevel@tonic-gate 	(void) printf("Verbose mode %s.\n", onoff(verbose));
958*7c478bd9Sstevel@tonic-gate 	code = verbose;
959*7c478bd9Sstevel@tonic-gate }
960*7c478bd9Sstevel@tonic-gate 
961*7c478bd9Sstevel@tonic-gate /*
962*7c478bd9Sstevel@tonic-gate  * Toggle PORT cmd use before each data connection.
963*7c478bd9Sstevel@tonic-gate  */
964*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
965*7c478bd9Sstevel@tonic-gate void
966*7c478bd9Sstevel@tonic-gate setport(int argc, char *argv[])
967*7c478bd9Sstevel@tonic-gate {
968*7c478bd9Sstevel@tonic-gate 	sendport = !sendport;
969*7c478bd9Sstevel@tonic-gate 	(void) printf("Use of PORT cmds %s.\n", onoff(sendport));
970*7c478bd9Sstevel@tonic-gate 	code = sendport;
971*7c478bd9Sstevel@tonic-gate }
972*7c478bd9Sstevel@tonic-gate 
973*7c478bd9Sstevel@tonic-gate /*
974*7c478bd9Sstevel@tonic-gate  * Turn on interactive prompting
975*7c478bd9Sstevel@tonic-gate  * during mget, mput, and mdelete.
976*7c478bd9Sstevel@tonic-gate  */
977*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
978*7c478bd9Sstevel@tonic-gate void
979*7c478bd9Sstevel@tonic-gate setprompt(int argc, char *argv[])
980*7c478bd9Sstevel@tonic-gate {
981*7c478bd9Sstevel@tonic-gate 	interactive = !interactive;
982*7c478bd9Sstevel@tonic-gate 	(void) printf("Interactive mode %s.\n", onoff(interactive));
983*7c478bd9Sstevel@tonic-gate 	code = interactive;
984*7c478bd9Sstevel@tonic-gate }
985*7c478bd9Sstevel@tonic-gate 
986*7c478bd9Sstevel@tonic-gate /*
987*7c478bd9Sstevel@tonic-gate  * Toggle metacharacter interpretation
988*7c478bd9Sstevel@tonic-gate  * on local file names.
989*7c478bd9Sstevel@tonic-gate  */
990*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
991*7c478bd9Sstevel@tonic-gate void
992*7c478bd9Sstevel@tonic-gate setglob(int argc, char *argv[])
993*7c478bd9Sstevel@tonic-gate {
994*7c478bd9Sstevel@tonic-gate 	doglob = !doglob;
995*7c478bd9Sstevel@tonic-gate 	(void) printf("Globbing %s.\n", onoff(doglob));
996*7c478bd9Sstevel@tonic-gate 	code = doglob;
997*7c478bd9Sstevel@tonic-gate }
998*7c478bd9Sstevel@tonic-gate 
999*7c478bd9Sstevel@tonic-gate /*
1000*7c478bd9Sstevel@tonic-gate  * Set debugging mode on/off and/or
1001*7c478bd9Sstevel@tonic-gate  * set level of debugging.
1002*7c478bd9Sstevel@tonic-gate  */
1003*7c478bd9Sstevel@tonic-gate void
1004*7c478bd9Sstevel@tonic-gate setdebug(int argc, char *argv[])
1005*7c478bd9Sstevel@tonic-gate {
1006*7c478bd9Sstevel@tonic-gate 	int val;
1007*7c478bd9Sstevel@tonic-gate 
1008*7c478bd9Sstevel@tonic-gate 	if (argc > 1) {
1009*7c478bd9Sstevel@tonic-gate 		val = atoi(argv[1]);
1010*7c478bd9Sstevel@tonic-gate 		if (val < 0) {
1011*7c478bd9Sstevel@tonic-gate 			(void) printf("%s: bad debugging value.\n", argv[1]);
1012*7c478bd9Sstevel@tonic-gate 			code = -1;
1013*7c478bd9Sstevel@tonic-gate 			return;
1014*7c478bd9Sstevel@tonic-gate 		}
1015*7c478bd9Sstevel@tonic-gate 	} else
1016*7c478bd9Sstevel@tonic-gate 		val = !debug;
1017*7c478bd9Sstevel@tonic-gate 	debug = val;
1018*7c478bd9Sstevel@tonic-gate 	if (debug)
1019*7c478bd9Sstevel@tonic-gate 		options |= SO_DEBUG;
1020*7c478bd9Sstevel@tonic-gate 	else
1021*7c478bd9Sstevel@tonic-gate 		options &= ~SO_DEBUG;
1022*7c478bd9Sstevel@tonic-gate 	(void) printf("Debugging %s (debug=%d).\n", onoff(debug), debug);
1023*7c478bd9Sstevel@tonic-gate 	code = debug > 0;
1024*7c478bd9Sstevel@tonic-gate }
1025*7c478bd9Sstevel@tonic-gate 
1026*7c478bd9Sstevel@tonic-gate /*
1027*7c478bd9Sstevel@tonic-gate  * Set current working directory
1028*7c478bd9Sstevel@tonic-gate  * on remote machine.
1029*7c478bd9Sstevel@tonic-gate  */
1030*7c478bd9Sstevel@tonic-gate void
1031*7c478bd9Sstevel@tonic-gate cd(int argc, char *argv[])
1032*7c478bd9Sstevel@tonic-gate {
1033*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1034*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "remote-directory") <
1035*7c478bd9Sstevel@tonic-gate 		    0) {
1036*7c478bd9Sstevel@tonic-gate 			code = -1;
1037*7c478bd9Sstevel@tonic-gate 			return;
1038*7c478bd9Sstevel@tonic-gate 		}
1039*7c478bd9Sstevel@tonic-gate 		makeargv();
1040*7c478bd9Sstevel@tonic-gate 		argc = margc;
1041*7c478bd9Sstevel@tonic-gate 		argv = margv;
1042*7c478bd9Sstevel@tonic-gate 	}
1043*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1044*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s remote-directory\n", argv[0]);
1045*7c478bd9Sstevel@tonic-gate 		code = -1;
1046*7c478bd9Sstevel@tonic-gate 		return;
1047*7c478bd9Sstevel@tonic-gate 	}
1048*7c478bd9Sstevel@tonic-gate 	(void) command("CWD %s", argv[1]);
1049*7c478bd9Sstevel@tonic-gate }
1050*7c478bd9Sstevel@tonic-gate 
1051*7c478bd9Sstevel@tonic-gate /*
1052*7c478bd9Sstevel@tonic-gate  * Set current working directory
1053*7c478bd9Sstevel@tonic-gate  * on local machine.
1054*7c478bd9Sstevel@tonic-gate  */
1055*7c478bd9Sstevel@tonic-gate void
1056*7c478bd9Sstevel@tonic-gate lcd(int argc, char *argv[])
1057*7c478bd9Sstevel@tonic-gate {
1058*7c478bd9Sstevel@tonic-gate 	char buf[MAXPATHLEN], *bufptr;
1059*7c478bd9Sstevel@tonic-gate 
1060*7c478bd9Sstevel@tonic-gate 	if (argc < 2)
1061*7c478bd9Sstevel@tonic-gate 		argc++, argv[1] = home;
1062*7c478bd9Sstevel@tonic-gate 	if (argc != 2) {
1063*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s local-directory\n", argv[0]);
1064*7c478bd9Sstevel@tonic-gate 		code = -1;
1065*7c478bd9Sstevel@tonic-gate 		return;
1066*7c478bd9Sstevel@tonic-gate 	}
1067*7c478bd9Sstevel@tonic-gate 	if (!globulize(&argv[1])) {
1068*7c478bd9Sstevel@tonic-gate 		code = -1;
1069*7c478bd9Sstevel@tonic-gate 		return;
1070*7c478bd9Sstevel@tonic-gate 	}
1071*7c478bd9Sstevel@tonic-gate 	if (chdir(argv[1]) < 0) {
1072*7c478bd9Sstevel@tonic-gate 		perror(argv[1]);
1073*7c478bd9Sstevel@tonic-gate 		code = -1;
1074*7c478bd9Sstevel@tonic-gate 		return;
1075*7c478bd9Sstevel@tonic-gate 	}
1076*7c478bd9Sstevel@tonic-gate 	bufptr = getcwd(buf, MAXPATHLEN);
1077*7c478bd9Sstevel@tonic-gate 	/*
1078*7c478bd9Sstevel@tonic-gate 	 * Even though chdir may succeed, getcwd may fail if a component
1079*7c478bd9Sstevel@tonic-gate 	 * of the pwd is unreadable. In this case, print the argument to
1080*7c478bd9Sstevel@tonic-gate 	 * chdir as the resultant directory, since we know it succeeded above.
1081*7c478bd9Sstevel@tonic-gate 	 */
1082*7c478bd9Sstevel@tonic-gate 	(void) printf("Local directory now %s\n", (bufptr ? bufptr : argv[1]));
1083*7c478bd9Sstevel@tonic-gate 	code = 0;
1084*7c478bd9Sstevel@tonic-gate }
1085*7c478bd9Sstevel@tonic-gate 
1086*7c478bd9Sstevel@tonic-gate /*
1087*7c478bd9Sstevel@tonic-gate  * Delete a single file.
1088*7c478bd9Sstevel@tonic-gate  */
1089*7c478bd9Sstevel@tonic-gate void
1090*7c478bd9Sstevel@tonic-gate delete(int argc, char *argv[])
1091*7c478bd9Sstevel@tonic-gate {
1092*7c478bd9Sstevel@tonic-gate 
1093*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1094*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "remote-file") < 0) {
1095*7c478bd9Sstevel@tonic-gate 			code = -1;
1096*7c478bd9Sstevel@tonic-gate 			return;
1097*7c478bd9Sstevel@tonic-gate 		}
1098*7c478bd9Sstevel@tonic-gate 		makeargv();
1099*7c478bd9Sstevel@tonic-gate 		argc = margc;
1100*7c478bd9Sstevel@tonic-gate 		argv = margv;
1101*7c478bd9Sstevel@tonic-gate 	}
1102*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1103*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s remote-file\n", argv[0]);
1104*7c478bd9Sstevel@tonic-gate 		code = -1;
1105*7c478bd9Sstevel@tonic-gate 		return;
1106*7c478bd9Sstevel@tonic-gate 	}
1107*7c478bd9Sstevel@tonic-gate 	(void) command("DELE %s", argv[1]);
1108*7c478bd9Sstevel@tonic-gate }
1109*7c478bd9Sstevel@tonic-gate 
1110*7c478bd9Sstevel@tonic-gate /*
1111*7c478bd9Sstevel@tonic-gate  * Delete multiple files.
1112*7c478bd9Sstevel@tonic-gate  */
1113*7c478bd9Sstevel@tonic-gate void
1114*7c478bd9Sstevel@tonic-gate mdelete(int argc, char *argv[])
1115*7c478bd9Sstevel@tonic-gate {
1116*7c478bd9Sstevel@tonic-gate 	char *cp;
1117*7c478bd9Sstevel@tonic-gate 	int ointer;
1118*7c478bd9Sstevel@tonic-gate 	void (*oldintr)();
1119*7c478bd9Sstevel@tonic-gate 
1120*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1121*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "remote-files") < 0) {
1122*7c478bd9Sstevel@tonic-gate 			code = -1;
1123*7c478bd9Sstevel@tonic-gate 			return;
1124*7c478bd9Sstevel@tonic-gate 		}
1125*7c478bd9Sstevel@tonic-gate 		makeargv();
1126*7c478bd9Sstevel@tonic-gate 		argc = margc;
1127*7c478bd9Sstevel@tonic-gate 		argv = margv;
1128*7c478bd9Sstevel@tonic-gate 	}
1129*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1130*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s remote-files\n", argv[0]);
1131*7c478bd9Sstevel@tonic-gate 		code = -1;
1132*7c478bd9Sstevel@tonic-gate 		return;
1133*7c478bd9Sstevel@tonic-gate 	}
1134*7c478bd9Sstevel@tonic-gate 	mname = argv[0];
1135*7c478bd9Sstevel@tonic-gate 	mflag = 1;
1136*7c478bd9Sstevel@tonic-gate 	oldintr = signal(SIGINT, mabort);
1137*7c478bd9Sstevel@tonic-gate 	(void) setjmp(jabort);
1138*7c478bd9Sstevel@tonic-gate 	while ((cp = remglob(argv, 0)) != NULL) {
1139*7c478bd9Sstevel@tonic-gate 		if (*cp == '\0') {
1140*7c478bd9Sstevel@tonic-gate 			mflag = 0;
1141*7c478bd9Sstevel@tonic-gate 			continue;
1142*7c478bd9Sstevel@tonic-gate 		}
1143*7c478bd9Sstevel@tonic-gate 		if (mflag && confirm(argv[0], cp)) {
1144*7c478bd9Sstevel@tonic-gate 			(void) command("DELE %s", cp);
1145*7c478bd9Sstevel@tonic-gate 			if (!mflag && fromatty) {
1146*7c478bd9Sstevel@tonic-gate 				ointer = interactive;
1147*7c478bd9Sstevel@tonic-gate 				interactive = 1;
1148*7c478bd9Sstevel@tonic-gate 				if (confirm("Continue with", "mdelete")) {
1149*7c478bd9Sstevel@tonic-gate 					mflag++;
1150*7c478bd9Sstevel@tonic-gate 				}
1151*7c478bd9Sstevel@tonic-gate 				interactive = ointer;
1152*7c478bd9Sstevel@tonic-gate 			}
1153*7c478bd9Sstevel@tonic-gate 		}
1154*7c478bd9Sstevel@tonic-gate 	}
1155*7c478bd9Sstevel@tonic-gate 	(void) signal(SIGINT, oldintr);
1156*7c478bd9Sstevel@tonic-gate 	mflag = 0;
1157*7c478bd9Sstevel@tonic-gate }
1158*7c478bd9Sstevel@tonic-gate 
1159*7c478bd9Sstevel@tonic-gate /*
1160*7c478bd9Sstevel@tonic-gate  * Rename a remote file.
1161*7c478bd9Sstevel@tonic-gate  */
1162*7c478bd9Sstevel@tonic-gate void
1163*7c478bd9Sstevel@tonic-gate renamefile(int argc, char *argv[])
1164*7c478bd9Sstevel@tonic-gate {
1165*7c478bd9Sstevel@tonic-gate 
1166*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1167*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "from-name") < 0) {
1168*7c478bd9Sstevel@tonic-gate 			code = -1;
1169*7c478bd9Sstevel@tonic-gate 			return;
1170*7c478bd9Sstevel@tonic-gate 		}
1171*7c478bd9Sstevel@tonic-gate 		makeargv();
1172*7c478bd9Sstevel@tonic-gate 		argc = margc;
1173*7c478bd9Sstevel@tonic-gate 		argv = margv;
1174*7c478bd9Sstevel@tonic-gate 	}
1175*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1176*7c478bd9Sstevel@tonic-gate usage:
1177*7c478bd9Sstevel@tonic-gate 		(void) printf("%s from-name to-name\n", argv[0]);
1178*7c478bd9Sstevel@tonic-gate 		code = -1;
1179*7c478bd9Sstevel@tonic-gate 		return;
1180*7c478bd9Sstevel@tonic-gate 	}
1181*7c478bd9Sstevel@tonic-gate 	if (argc < 3) {
1182*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "to-name") < 0) {
1183*7c478bd9Sstevel@tonic-gate 			code = -1;
1184*7c478bd9Sstevel@tonic-gate 			return;
1185*7c478bd9Sstevel@tonic-gate 		}
1186*7c478bd9Sstevel@tonic-gate 		makeargv();
1187*7c478bd9Sstevel@tonic-gate 		argc = margc;
1188*7c478bd9Sstevel@tonic-gate 		argv = margv;
1189*7c478bd9Sstevel@tonic-gate 	}
1190*7c478bd9Sstevel@tonic-gate 	if (argc < 3)
1191*7c478bd9Sstevel@tonic-gate 		goto usage;
1192*7c478bd9Sstevel@tonic-gate 	if (command("RNFR %s", argv[1]) == CONTINUE)
1193*7c478bd9Sstevel@tonic-gate 		(void) command("RNTO %s", argv[2]);
1194*7c478bd9Sstevel@tonic-gate }
1195*7c478bd9Sstevel@tonic-gate 
1196*7c478bd9Sstevel@tonic-gate /*
1197*7c478bd9Sstevel@tonic-gate  * Get a directory listing
1198*7c478bd9Sstevel@tonic-gate  * of remote files.
1199*7c478bd9Sstevel@tonic-gate  */
1200*7c478bd9Sstevel@tonic-gate void
1201*7c478bd9Sstevel@tonic-gate ls(int argc, char *argv[])
1202*7c478bd9Sstevel@tonic-gate {
1203*7c478bd9Sstevel@tonic-gate 	char *cmd;
1204*7c478bd9Sstevel@tonic-gate 
1205*7c478bd9Sstevel@tonic-gate 	if (argc < 2)
1206*7c478bd9Sstevel@tonic-gate 		argc++, argv[1] = NULL;
1207*7c478bd9Sstevel@tonic-gate 	if (argc < 3)
1208*7c478bd9Sstevel@tonic-gate 		argc++, argv[2] = "-";
1209*7c478bd9Sstevel@tonic-gate 	if (argc > 3) {
1210*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s remote-directory local-file\n",
1211*7c478bd9Sstevel@tonic-gate 			argv[0]);
1212*7c478bd9Sstevel@tonic-gate 		code = -1;
1213*7c478bd9Sstevel@tonic-gate 		return;
1214*7c478bd9Sstevel@tonic-gate 	}
1215*7c478bd9Sstevel@tonic-gate 	if (ls_invokes_NLST) {
1216*7c478bd9Sstevel@tonic-gate 		cmd = ((argv[0][0] == 'l' || argv[0][0] == 'n') ?
1217*7c478bd9Sstevel@tonic-gate 		    "NLST" : "LIST");
1218*7c478bd9Sstevel@tonic-gate 	} else {
1219*7c478bd9Sstevel@tonic-gate 		cmd = ((argv[0][0] == 'n') ? "NLST" : "LIST");
1220*7c478bd9Sstevel@tonic-gate 	}
1221*7c478bd9Sstevel@tonic-gate 	if (strcmp(argv[2], "-") && !globulize(&argv[2])) {
1222*7c478bd9Sstevel@tonic-gate 		code = -1;
1223*7c478bd9Sstevel@tonic-gate 		return;
1224*7c478bd9Sstevel@tonic-gate 	}
1225*7c478bd9Sstevel@tonic-gate 	recvrequest(cmd, argv[2], argv[1], "w", 1);
1226*7c478bd9Sstevel@tonic-gate }
1227*7c478bd9Sstevel@tonic-gate 
1228*7c478bd9Sstevel@tonic-gate /*
1229*7c478bd9Sstevel@tonic-gate  * Get a directory listing
1230*7c478bd9Sstevel@tonic-gate  * of multiple remote files.
1231*7c478bd9Sstevel@tonic-gate  */
1232*7c478bd9Sstevel@tonic-gate void
1233*7c478bd9Sstevel@tonic-gate mls(int argc, char *argv[])
1234*7c478bd9Sstevel@tonic-gate {
1235*7c478bd9Sstevel@tonic-gate 	char *cmd, mode[1], *dest;
1236*7c478bd9Sstevel@tonic-gate 	int ointer, i;
1237*7c478bd9Sstevel@tonic-gate 	void (*oldintr)();
1238*7c478bd9Sstevel@tonic-gate 
1239*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1240*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "remote-files") < 0) {
1241*7c478bd9Sstevel@tonic-gate 			code = -1;
1242*7c478bd9Sstevel@tonic-gate 			return;
1243*7c478bd9Sstevel@tonic-gate 		}
1244*7c478bd9Sstevel@tonic-gate 		makeargv();
1245*7c478bd9Sstevel@tonic-gate 		argc = margc;
1246*7c478bd9Sstevel@tonic-gate 		argv = margv;
1247*7c478bd9Sstevel@tonic-gate 	}
1248*7c478bd9Sstevel@tonic-gate 	if (argc < 3) {
1249*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "local-file") < 0) {
1250*7c478bd9Sstevel@tonic-gate 			code = -1;
1251*7c478bd9Sstevel@tonic-gate 			return;
1252*7c478bd9Sstevel@tonic-gate 		}
1253*7c478bd9Sstevel@tonic-gate 		makeargv();
1254*7c478bd9Sstevel@tonic-gate 		argc = margc;
1255*7c478bd9Sstevel@tonic-gate 		argv = margv;
1256*7c478bd9Sstevel@tonic-gate 	}
1257*7c478bd9Sstevel@tonic-gate 	if (argc < 3) {
1258*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s remote-files local-file\n", argv[0]);
1259*7c478bd9Sstevel@tonic-gate 		code = -1;
1260*7c478bd9Sstevel@tonic-gate 		return;
1261*7c478bd9Sstevel@tonic-gate 	}
1262*7c478bd9Sstevel@tonic-gate 	dest = argv[argc - 1];
1263*7c478bd9Sstevel@tonic-gate 	argv[argc - 1] = NULL;
1264*7c478bd9Sstevel@tonic-gate 	if (strcmp(dest, "-") && *dest != '|')
1265*7c478bd9Sstevel@tonic-gate 		if (!globulize(&dest) ||
1266*7c478bd9Sstevel@tonic-gate 		    !confirm("output to local-file:", dest)) {
1267*7c478bd9Sstevel@tonic-gate 			code = -1;
1268*7c478bd9Sstevel@tonic-gate 			return;
1269*7c478bd9Sstevel@tonic-gate 		}
1270*7c478bd9Sstevel@tonic-gate 	cmd = argv[0][1] == 'l' ? "NLST" : "LIST";
1271*7c478bd9Sstevel@tonic-gate 	mname = argv[0];
1272*7c478bd9Sstevel@tonic-gate 	mflag = 1;
1273*7c478bd9Sstevel@tonic-gate 	oldintr = signal(SIGINT, mabort);
1274*7c478bd9Sstevel@tonic-gate 	(void) setjmp(jabort);
1275*7c478bd9Sstevel@tonic-gate 	for (i = 1; mflag && i < argc-1; ++i) {
1276*7c478bd9Sstevel@tonic-gate 		*mode = (i == 1) ? 'w' : 'a';
1277*7c478bd9Sstevel@tonic-gate 		recvrequest(cmd, dest, argv[i], mode, 1);
1278*7c478bd9Sstevel@tonic-gate 		if (!mflag && fromatty) {
1279*7c478bd9Sstevel@tonic-gate 			ointer = interactive;
1280*7c478bd9Sstevel@tonic-gate 			interactive = 1;
1281*7c478bd9Sstevel@tonic-gate 			if (confirm("Continue with", argv[0])) {
1282*7c478bd9Sstevel@tonic-gate 				mflag ++;
1283*7c478bd9Sstevel@tonic-gate 			}
1284*7c478bd9Sstevel@tonic-gate 			interactive = ointer;
1285*7c478bd9Sstevel@tonic-gate 		}
1286*7c478bd9Sstevel@tonic-gate 	}
1287*7c478bd9Sstevel@tonic-gate 	(void) signal(SIGINT, oldintr);
1288*7c478bd9Sstevel@tonic-gate 	mflag = 0;
1289*7c478bd9Sstevel@tonic-gate }
1290*7c478bd9Sstevel@tonic-gate 
1291*7c478bd9Sstevel@tonic-gate /*
1292*7c478bd9Sstevel@tonic-gate  * Do a shell escape
1293*7c478bd9Sstevel@tonic-gate  */
1294*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1295*7c478bd9Sstevel@tonic-gate void
1296*7c478bd9Sstevel@tonic-gate shell(int argc, char *argv[])
1297*7c478bd9Sstevel@tonic-gate {
1298*7c478bd9Sstevel@tonic-gate 	pid_t pid;
1299*7c478bd9Sstevel@tonic-gate 	void (*old1)(), (*old2)();
1300*7c478bd9Sstevel@tonic-gate 	char *shellstring, *namep;
1301*7c478bd9Sstevel@tonic-gate 	int status;
1302*7c478bd9Sstevel@tonic-gate 
1303*7c478bd9Sstevel@tonic-gate 	stop_timer();
1304*7c478bd9Sstevel@tonic-gate 	old1 = signal(SIGINT, SIG_IGN);
1305*7c478bd9Sstevel@tonic-gate 	old2 = signal(SIGQUIT, SIG_IGN);
1306*7c478bd9Sstevel@tonic-gate 	if ((pid = fork()) == 0) {
1307*7c478bd9Sstevel@tonic-gate 		closefrom(STDERR_FILENO + 1);
1308*7c478bd9Sstevel@tonic-gate 		(void) signal(SIGINT, SIG_DFL);
1309*7c478bd9Sstevel@tonic-gate 		(void) signal(SIGQUIT, SIG_DFL);
1310*7c478bd9Sstevel@tonic-gate 		shellstring = getenv("SHELL");
1311*7c478bd9Sstevel@tonic-gate 		if (shellstring == NULL)
1312*7c478bd9Sstevel@tonic-gate 			shellstring = "/bin/sh";
1313*7c478bd9Sstevel@tonic-gate 		namep = rindex(shellstring, '/');
1314*7c478bd9Sstevel@tonic-gate 		if (namep == NULL)
1315*7c478bd9Sstevel@tonic-gate 			namep = shellstring;
1316*7c478bd9Sstevel@tonic-gate 		if (argc > 1) {
1317*7c478bd9Sstevel@tonic-gate 			if (debug) {
1318*7c478bd9Sstevel@tonic-gate 				(void) printf("%s -c %s\n", shellstring,
1319*7c478bd9Sstevel@tonic-gate 					altarg);
1320*7c478bd9Sstevel@tonic-gate 				(void) fflush(stdout);
1321*7c478bd9Sstevel@tonic-gate 			}
1322*7c478bd9Sstevel@tonic-gate 			execl(shellstring, namep, "-c", altarg, (char *)0);
1323*7c478bd9Sstevel@tonic-gate 		} else {
1324*7c478bd9Sstevel@tonic-gate 			if (debug) {
1325*7c478bd9Sstevel@tonic-gate 				(void) printf("%s\n", shellstring);
1326*7c478bd9Sstevel@tonic-gate 				(void) fflush(stdout);
1327*7c478bd9Sstevel@tonic-gate 			}
1328*7c478bd9Sstevel@tonic-gate 			execl(shellstring, namep, (char *)0);
1329*7c478bd9Sstevel@tonic-gate 		}
1330*7c478bd9Sstevel@tonic-gate 		perror(shellstring);
1331*7c478bd9Sstevel@tonic-gate 		code = -1;
1332*7c478bd9Sstevel@tonic-gate 		exit(1);
1333*7c478bd9Sstevel@tonic-gate 		}
1334*7c478bd9Sstevel@tonic-gate 	if (pid > 0)
1335*7c478bd9Sstevel@tonic-gate 		while (wait(&status) != pid)
1336*7c478bd9Sstevel@tonic-gate 			;
1337*7c478bd9Sstevel@tonic-gate 	(void) signal(SIGINT, old1);
1338*7c478bd9Sstevel@tonic-gate 	(void) signal(SIGQUIT, old2);
1339*7c478bd9Sstevel@tonic-gate 	reset_timer();
1340*7c478bd9Sstevel@tonic-gate 	if (pid == (pid_t)-1) {
1341*7c478bd9Sstevel@tonic-gate 		perror("Try again later");
1342*7c478bd9Sstevel@tonic-gate 		code = -1;
1343*7c478bd9Sstevel@tonic-gate 	} else {
1344*7c478bd9Sstevel@tonic-gate 		code = 0;
1345*7c478bd9Sstevel@tonic-gate 	}
1346*7c478bd9Sstevel@tonic-gate }
1347*7c478bd9Sstevel@tonic-gate 
1348*7c478bd9Sstevel@tonic-gate /*
1349*7c478bd9Sstevel@tonic-gate  * Send new user information (re-login)
1350*7c478bd9Sstevel@tonic-gate  */
1351*7c478bd9Sstevel@tonic-gate void
1352*7c478bd9Sstevel@tonic-gate user(int argc, char *argv[])
1353*7c478bd9Sstevel@tonic-gate {
1354*7c478bd9Sstevel@tonic-gate 	char acct[80];
1355*7c478bd9Sstevel@tonic-gate 	int n, aflag = 0;
1356*7c478bd9Sstevel@tonic-gate 
1357*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1358*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "username") < 0) {
1359*7c478bd9Sstevel@tonic-gate 			code = -1;
1360*7c478bd9Sstevel@tonic-gate 			return;
1361*7c478bd9Sstevel@tonic-gate 		}
1362*7c478bd9Sstevel@tonic-gate 		makeargv();
1363*7c478bd9Sstevel@tonic-gate 		argc = margc;
1364*7c478bd9Sstevel@tonic-gate 		argv = margv;
1365*7c478bd9Sstevel@tonic-gate 	}
1366*7c478bd9Sstevel@tonic-gate 	if (argc > 4) {
1367*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s username [password] [account]\n",
1368*7c478bd9Sstevel@tonic-gate 			argv[0]);
1369*7c478bd9Sstevel@tonic-gate 		code = -1;
1370*7c478bd9Sstevel@tonic-gate 		return;
1371*7c478bd9Sstevel@tonic-gate 	}
1372*7c478bd9Sstevel@tonic-gate 	if (argv[1] == 0) {
1373*7c478bd9Sstevel@tonic-gate 		(void) printf("access for user (nil) denied\n");
1374*7c478bd9Sstevel@tonic-gate 		code = -1;
1375*7c478bd9Sstevel@tonic-gate 		return;
1376*7c478bd9Sstevel@tonic-gate 	}
1377*7c478bd9Sstevel@tonic-gate 	n = command("USER %s", argv[1]);
1378*7c478bd9Sstevel@tonic-gate 	if (n == CONTINUE) {
1379*7c478bd9Sstevel@tonic-gate 		int oldclevel;
1380*7c478bd9Sstevel@tonic-gate 		if (argc < 3)
1381*7c478bd9Sstevel@tonic-gate 			argv[2] = mygetpass("Password: "), argc++;
1382*7c478bd9Sstevel@tonic-gate 		if ((oldclevel = clevel) == PROT_S)
1383*7c478bd9Sstevel@tonic-gate 			clevel = PROT_P;
1384*7c478bd9Sstevel@tonic-gate 		n = command("PASS %s", argv[2]);
1385*7c478bd9Sstevel@tonic-gate 		/* level may have changed */
1386*7c478bd9Sstevel@tonic-gate 		if (clevel == PROT_P)
1387*7c478bd9Sstevel@tonic-gate 			clevel = oldclevel;
1388*7c478bd9Sstevel@tonic-gate 	}
1389*7c478bd9Sstevel@tonic-gate 	if (n == CONTINUE) {
1390*7c478bd9Sstevel@tonic-gate 		if (argc < 4) {
1391*7c478bd9Sstevel@tonic-gate 			(void) printf("Account: "); (void) fflush(stdout);
1392*7c478bd9Sstevel@tonic-gate 			stop_timer();
1393*7c478bd9Sstevel@tonic-gate 			(void) fgets(acct, sizeof (acct) - 1, stdin);
1394*7c478bd9Sstevel@tonic-gate 			reset_timer();
1395*7c478bd9Sstevel@tonic-gate 			acct[strlen(acct) - 1] = '\0';
1396*7c478bd9Sstevel@tonic-gate 			argv[3] = acct; argc++;
1397*7c478bd9Sstevel@tonic-gate 		}
1398*7c478bd9Sstevel@tonic-gate 		n = command("ACCT %s", argv[3]);
1399*7c478bd9Sstevel@tonic-gate 		aflag++;
1400*7c478bd9Sstevel@tonic-gate 	}
1401*7c478bd9Sstevel@tonic-gate 	if (n != COMPLETE) {
1402*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout, "Login failed.\n");
1403*7c478bd9Sstevel@tonic-gate 		return;
1404*7c478bd9Sstevel@tonic-gate 	}
1405*7c478bd9Sstevel@tonic-gate 	if (!aflag && argc == 4) {
1406*7c478bd9Sstevel@tonic-gate 		(void) command("ACCT %s", argv[3]);
1407*7c478bd9Sstevel@tonic-gate 	}
1408*7c478bd9Sstevel@tonic-gate }
1409*7c478bd9Sstevel@tonic-gate 
1410*7c478bd9Sstevel@tonic-gate /*
1411*7c478bd9Sstevel@tonic-gate  * Print working directory.
1412*7c478bd9Sstevel@tonic-gate  */
1413*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1414*7c478bd9Sstevel@tonic-gate void
1415*7c478bd9Sstevel@tonic-gate pwd(int argc, char *argv[])
1416*7c478bd9Sstevel@tonic-gate {
1417*7c478bd9Sstevel@tonic-gate 	(void) command("PWD");
1418*7c478bd9Sstevel@tonic-gate }
1419*7c478bd9Sstevel@tonic-gate 
1420*7c478bd9Sstevel@tonic-gate /*
1421*7c478bd9Sstevel@tonic-gate  * Make a directory.
1422*7c478bd9Sstevel@tonic-gate  */
1423*7c478bd9Sstevel@tonic-gate void
1424*7c478bd9Sstevel@tonic-gate makedir(int argc, char *argv[])
1425*7c478bd9Sstevel@tonic-gate {
1426*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1427*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "directory-name") <
1428*7c478bd9Sstevel@tonic-gate 		    0) {
1429*7c478bd9Sstevel@tonic-gate 			code = -1;
1430*7c478bd9Sstevel@tonic-gate 			return;
1431*7c478bd9Sstevel@tonic-gate 		}
1432*7c478bd9Sstevel@tonic-gate 		makeargv();
1433*7c478bd9Sstevel@tonic-gate 		argc = margc;
1434*7c478bd9Sstevel@tonic-gate 		argv = margv;
1435*7c478bd9Sstevel@tonic-gate 	}
1436*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1437*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s directory-name\n", argv[0]);
1438*7c478bd9Sstevel@tonic-gate 		code = -1;
1439*7c478bd9Sstevel@tonic-gate 		return;
1440*7c478bd9Sstevel@tonic-gate 	}
1441*7c478bd9Sstevel@tonic-gate 	(void) command("MKD %s", argv[1]);
1442*7c478bd9Sstevel@tonic-gate }
1443*7c478bd9Sstevel@tonic-gate 
1444*7c478bd9Sstevel@tonic-gate /*
1445*7c478bd9Sstevel@tonic-gate  * Remove a directory.
1446*7c478bd9Sstevel@tonic-gate  */
1447*7c478bd9Sstevel@tonic-gate void
1448*7c478bd9Sstevel@tonic-gate removedir(int argc, char *argv[])
1449*7c478bd9Sstevel@tonic-gate {
1450*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1451*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "directory-name") <
1452*7c478bd9Sstevel@tonic-gate 		    0) {
1453*7c478bd9Sstevel@tonic-gate 			code = -1;
1454*7c478bd9Sstevel@tonic-gate 			return;
1455*7c478bd9Sstevel@tonic-gate 		}
1456*7c478bd9Sstevel@tonic-gate 		makeargv();
1457*7c478bd9Sstevel@tonic-gate 		argc = margc;
1458*7c478bd9Sstevel@tonic-gate 		argv = margv;
1459*7c478bd9Sstevel@tonic-gate 	}
1460*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1461*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s directory-name\n", argv[0]);
1462*7c478bd9Sstevel@tonic-gate 		code = -1;
1463*7c478bd9Sstevel@tonic-gate 		return;
1464*7c478bd9Sstevel@tonic-gate 	}
1465*7c478bd9Sstevel@tonic-gate 	(void) command("RMD %s", argv[1]);
1466*7c478bd9Sstevel@tonic-gate }
1467*7c478bd9Sstevel@tonic-gate 
1468*7c478bd9Sstevel@tonic-gate /*
1469*7c478bd9Sstevel@tonic-gate  * Send a line, verbatim, to the remote machine.
1470*7c478bd9Sstevel@tonic-gate  */
1471*7c478bd9Sstevel@tonic-gate void
1472*7c478bd9Sstevel@tonic-gate quote(int argc, char *argv[])
1473*7c478bd9Sstevel@tonic-gate {
1474*7c478bd9Sstevel@tonic-gate 	int i, n, len;
1475*7c478bd9Sstevel@tonic-gate 	char buf[FTPBUFSIZ];
1476*7c478bd9Sstevel@tonic-gate 
1477*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1478*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line),
1479*7c478bd9Sstevel@tonic-gate 		    "command line to send") == -1) {
1480*7c478bd9Sstevel@tonic-gate 			code = -1;
1481*7c478bd9Sstevel@tonic-gate 			return;
1482*7c478bd9Sstevel@tonic-gate 		}
1483*7c478bd9Sstevel@tonic-gate 		makeargv();
1484*7c478bd9Sstevel@tonic-gate 		argc = margc;
1485*7c478bd9Sstevel@tonic-gate 		argv = margv;
1486*7c478bd9Sstevel@tonic-gate 	}
1487*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1488*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s line-to-send\n", argv[0]);
1489*7c478bd9Sstevel@tonic-gate 		code = -1;
1490*7c478bd9Sstevel@tonic-gate 		return;
1491*7c478bd9Sstevel@tonic-gate 	}
1492*7c478bd9Sstevel@tonic-gate 	len = snprintf(buf, sizeof (buf), "%s", argv[1]);
1493*7c478bd9Sstevel@tonic-gate 	if (len >= 0 && len < sizeof (buf) - 1) {
1494*7c478bd9Sstevel@tonic-gate 		for (i = 2; i < argc; i++) {
1495*7c478bd9Sstevel@tonic-gate 			n = snprintf(&buf[len], sizeof (buf) - len, " %s",
1496*7c478bd9Sstevel@tonic-gate 					argv[i]);
1497*7c478bd9Sstevel@tonic-gate 			if (n < 0 || n >= sizeof (buf) - len)
1498*7c478bd9Sstevel@tonic-gate 				break;
1499*7c478bd9Sstevel@tonic-gate 			len += n;
1500*7c478bd9Sstevel@tonic-gate 		}
1501*7c478bd9Sstevel@tonic-gate 	}
1502*7c478bd9Sstevel@tonic-gate 	if (command("%s", buf) == PRELIM) {
1503*7c478bd9Sstevel@tonic-gate 		while (getreply(0) == PRELIM)
1504*7c478bd9Sstevel@tonic-gate 			;
1505*7c478bd9Sstevel@tonic-gate 	}
1506*7c478bd9Sstevel@tonic-gate }
1507*7c478bd9Sstevel@tonic-gate 
1508*7c478bd9Sstevel@tonic-gate /*
1509*7c478bd9Sstevel@tonic-gate  * Send a line, verbatim, to the remote machine as a SITE command.
1510*7c478bd9Sstevel@tonic-gate  */
1511*7c478bd9Sstevel@tonic-gate void
1512*7c478bd9Sstevel@tonic-gate site(int argc, char *argv[])
1513*7c478bd9Sstevel@tonic-gate {
1514*7c478bd9Sstevel@tonic-gate 	int i, n, len;
1515*7c478bd9Sstevel@tonic-gate 	char buf[FTPBUFSIZ];
1516*7c478bd9Sstevel@tonic-gate 
1517*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1518*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line),
1519*7c478bd9Sstevel@tonic-gate 		    "arguments to SITE command") == -1) {
1520*7c478bd9Sstevel@tonic-gate 			code = -1;
1521*7c478bd9Sstevel@tonic-gate 			return;
1522*7c478bd9Sstevel@tonic-gate 		}
1523*7c478bd9Sstevel@tonic-gate 		makeargv();
1524*7c478bd9Sstevel@tonic-gate 		argc = margc;
1525*7c478bd9Sstevel@tonic-gate 		argv = margv;
1526*7c478bd9Sstevel@tonic-gate 	}
1527*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1528*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s arg1 [arg2] ...\n", argv[0]);
1529*7c478bd9Sstevel@tonic-gate 		code = -1;
1530*7c478bd9Sstevel@tonic-gate 		return;
1531*7c478bd9Sstevel@tonic-gate 	}
1532*7c478bd9Sstevel@tonic-gate 	len = snprintf(buf, sizeof (buf), "%s", argv[1]);
1533*7c478bd9Sstevel@tonic-gate 	if (len >= 0 && len < sizeof (buf) - 1) {
1534*7c478bd9Sstevel@tonic-gate 		for (i = 2; i < argc; i++) {
1535*7c478bd9Sstevel@tonic-gate 			n = snprintf(&buf[len], sizeof (buf) - len, " %s",
1536*7c478bd9Sstevel@tonic-gate 					argv[i]);
1537*7c478bd9Sstevel@tonic-gate 			if (n < 0 || n >= sizeof (buf) - len)
1538*7c478bd9Sstevel@tonic-gate 				break;
1539*7c478bd9Sstevel@tonic-gate 			len += n;
1540*7c478bd9Sstevel@tonic-gate 		}
1541*7c478bd9Sstevel@tonic-gate 	}
1542*7c478bd9Sstevel@tonic-gate 	if (command("SITE %s", buf) == PRELIM) {
1543*7c478bd9Sstevel@tonic-gate 		while (getreply(0) == PRELIM)
1544*7c478bd9Sstevel@tonic-gate 			;
1545*7c478bd9Sstevel@tonic-gate 	}
1546*7c478bd9Sstevel@tonic-gate }
1547*7c478bd9Sstevel@tonic-gate 
1548*7c478bd9Sstevel@tonic-gate /*
1549*7c478bd9Sstevel@tonic-gate  * Ask the other side for help.
1550*7c478bd9Sstevel@tonic-gate  */
1551*7c478bd9Sstevel@tonic-gate void
1552*7c478bd9Sstevel@tonic-gate rmthelp(int argc, char *argv[])
1553*7c478bd9Sstevel@tonic-gate {
1554*7c478bd9Sstevel@tonic-gate 	int oldverbose = verbose;
1555*7c478bd9Sstevel@tonic-gate 
1556*7c478bd9Sstevel@tonic-gate 	verbose = 1;
1557*7c478bd9Sstevel@tonic-gate 	(void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]);
1558*7c478bd9Sstevel@tonic-gate 	verbose = oldverbose;
1559*7c478bd9Sstevel@tonic-gate }
1560*7c478bd9Sstevel@tonic-gate 
1561*7c478bd9Sstevel@tonic-gate /*
1562*7c478bd9Sstevel@tonic-gate  * Terminate session and exit.
1563*7c478bd9Sstevel@tonic-gate  */
1564*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1565*7c478bd9Sstevel@tonic-gate void
1566*7c478bd9Sstevel@tonic-gate quit(int argc, char *argv[])
1567*7c478bd9Sstevel@tonic-gate {
1568*7c478bd9Sstevel@tonic-gate 	if (connected)
1569*7c478bd9Sstevel@tonic-gate 		disconnect(0, NULL);
1570*7c478bd9Sstevel@tonic-gate 	pswitch(1);
1571*7c478bd9Sstevel@tonic-gate 	if (connected) {
1572*7c478bd9Sstevel@tonic-gate 		disconnect(0, NULL);
1573*7c478bd9Sstevel@tonic-gate 	}
1574*7c478bd9Sstevel@tonic-gate 	exit(0);
1575*7c478bd9Sstevel@tonic-gate }
1576*7c478bd9Sstevel@tonic-gate 
1577*7c478bd9Sstevel@tonic-gate /*
1578*7c478bd9Sstevel@tonic-gate  * Terminate session, but don't exit.
1579*7c478bd9Sstevel@tonic-gate  */
1580*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1581*7c478bd9Sstevel@tonic-gate void
1582*7c478bd9Sstevel@tonic-gate disconnect(int argc, char *argv[])
1583*7c478bd9Sstevel@tonic-gate {
1584*7c478bd9Sstevel@tonic-gate 	extern FILE *ctrl_in, *ctrl_out;
1585*7c478bd9Sstevel@tonic-gate 	extern int data;
1586*7c478bd9Sstevel@tonic-gate 
1587*7c478bd9Sstevel@tonic-gate 	if (!connected)
1588*7c478bd9Sstevel@tonic-gate 		return;
1589*7c478bd9Sstevel@tonic-gate 	(void) command("QUIT");
1590*7c478bd9Sstevel@tonic-gate 	if (ctrl_in) {
1591*7c478bd9Sstevel@tonic-gate 		reset_timer();
1592*7c478bd9Sstevel@tonic-gate 		(void) fclose(ctrl_in);
1593*7c478bd9Sstevel@tonic-gate 	}
1594*7c478bd9Sstevel@tonic-gate 	if (ctrl_out) {
1595*7c478bd9Sstevel@tonic-gate 		reset_timer();
1596*7c478bd9Sstevel@tonic-gate 		(void) fclose(ctrl_out);
1597*7c478bd9Sstevel@tonic-gate 	}
1598*7c478bd9Sstevel@tonic-gate 	ctrl_out = ctrl_in = NULL;
1599*7c478bd9Sstevel@tonic-gate 	connected = 0;
1600*7c478bd9Sstevel@tonic-gate 	data = -1;
1601*7c478bd9Sstevel@tonic-gate 	if (!proxy) {
1602*7c478bd9Sstevel@tonic-gate 		macnum = 0;
1603*7c478bd9Sstevel@tonic-gate 	}
1604*7c478bd9Sstevel@tonic-gate 
1605*7c478bd9Sstevel@tonic-gate 	auth_type = AUTHTYPE_NONE;
1606*7c478bd9Sstevel@tonic-gate 	clevel = dlevel = PROT_C;
1607*7c478bd9Sstevel@tonic-gate 	goteof = 0;
1608*7c478bd9Sstevel@tonic-gate }
1609*7c478bd9Sstevel@tonic-gate 
1610*7c478bd9Sstevel@tonic-gate static int
1611*7c478bd9Sstevel@tonic-gate confirm(char *cmd, char *file)
1612*7c478bd9Sstevel@tonic-gate {
1613*7c478bd9Sstevel@tonic-gate 	char line[FTPBUFSIZ];
1614*7c478bd9Sstevel@tonic-gate 
1615*7c478bd9Sstevel@tonic-gate 	if (!interactive)
1616*7c478bd9Sstevel@tonic-gate 		return (1);
1617*7c478bd9Sstevel@tonic-gate 	stop_timer();
1618*7c478bd9Sstevel@tonic-gate 	(void) printf("%s %s? ", cmd, file);
1619*7c478bd9Sstevel@tonic-gate 	(void) fflush(stdout);
1620*7c478bd9Sstevel@tonic-gate 	*line = '\0';
1621*7c478bd9Sstevel@tonic-gate 	(void) fgets(line, sizeof (line), stdin);
1622*7c478bd9Sstevel@tonic-gate 	reset_timer();
1623*7c478bd9Sstevel@tonic-gate 	return (*line != 'n' && *line != 'N');
1624*7c478bd9Sstevel@tonic-gate }
1625*7c478bd9Sstevel@tonic-gate 
1626*7c478bd9Sstevel@tonic-gate void
1627*7c478bd9Sstevel@tonic-gate fatal(char *msg)
1628*7c478bd9Sstevel@tonic-gate {
1629*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "ftp: %s\n", msg);
1630*7c478bd9Sstevel@tonic-gate 	exit(1);
1631*7c478bd9Sstevel@tonic-gate }
1632*7c478bd9Sstevel@tonic-gate 
1633*7c478bd9Sstevel@tonic-gate /*
1634*7c478bd9Sstevel@tonic-gate  * Glob a local file name specification with
1635*7c478bd9Sstevel@tonic-gate  * the expectation of a single return value.
1636*7c478bd9Sstevel@tonic-gate  * Can't control multiple values being expanded
1637*7c478bd9Sstevel@tonic-gate  * from the expression, we return only the first.
1638*7c478bd9Sstevel@tonic-gate  */
1639*7c478bd9Sstevel@tonic-gate static int
1640*7c478bd9Sstevel@tonic-gate globulize(char **cpp)
1641*7c478bd9Sstevel@tonic-gate {
1642*7c478bd9Sstevel@tonic-gate 	char **globbed;
1643*7c478bd9Sstevel@tonic-gate 
1644*7c478bd9Sstevel@tonic-gate 	if (!doglob)
1645*7c478bd9Sstevel@tonic-gate 		return (1);
1646*7c478bd9Sstevel@tonic-gate 	globbed = glob(*cpp);
1647*7c478bd9Sstevel@tonic-gate 	if (globbed != NULL && *globbed == NULL && globerr == NULL)
1648*7c478bd9Sstevel@tonic-gate 		globerr = "No match";
1649*7c478bd9Sstevel@tonic-gate 	if (globerr != NULL) {
1650*7c478bd9Sstevel@tonic-gate 		(void) printf("%s: %s\n", *cpp, globerr);
1651*7c478bd9Sstevel@tonic-gate 		if (globbed)
1652*7c478bd9Sstevel@tonic-gate 			blkfree(globbed);
1653*7c478bd9Sstevel@tonic-gate 		return (0);
1654*7c478bd9Sstevel@tonic-gate 	}
1655*7c478bd9Sstevel@tonic-gate 	if (globbed) {
1656*7c478bd9Sstevel@tonic-gate 		*cpp = strdup(*globbed);
1657*7c478bd9Sstevel@tonic-gate 		blkfree(globbed);
1658*7c478bd9Sstevel@tonic-gate 		if (!*cpp)
1659*7c478bd9Sstevel@tonic-gate 			return (0);
1660*7c478bd9Sstevel@tonic-gate 	}
1661*7c478bd9Sstevel@tonic-gate 	return (1);
1662*7c478bd9Sstevel@tonic-gate }
1663*7c478bd9Sstevel@tonic-gate 
1664*7c478bd9Sstevel@tonic-gate void
1665*7c478bd9Sstevel@tonic-gate account(int argc, char *argv[])
1666*7c478bd9Sstevel@tonic-gate {
1667*7c478bd9Sstevel@tonic-gate 	char acct[50], *ap;
1668*7c478bd9Sstevel@tonic-gate 
1669*7c478bd9Sstevel@tonic-gate 	if (argc > 1) {
1670*7c478bd9Sstevel@tonic-gate 		++argv;
1671*7c478bd9Sstevel@tonic-gate 		--argc;
1672*7c478bd9Sstevel@tonic-gate 		(void) strncpy(acct, *argv, 49);
1673*7c478bd9Sstevel@tonic-gate 		acct[49] = '\0';
1674*7c478bd9Sstevel@tonic-gate 		while (argc > 1) {
1675*7c478bd9Sstevel@tonic-gate 			--argc;
1676*7c478bd9Sstevel@tonic-gate 			++argv;
1677*7c478bd9Sstevel@tonic-gate 			(void) strncat(acct, *argv, 49 - strlen(acct));
1678*7c478bd9Sstevel@tonic-gate 		}
1679*7c478bd9Sstevel@tonic-gate 		ap = acct;
1680*7c478bd9Sstevel@tonic-gate 	} else {
1681*7c478bd9Sstevel@tonic-gate 		ap = mygetpass("Account:");
1682*7c478bd9Sstevel@tonic-gate 	}
1683*7c478bd9Sstevel@tonic-gate 	(void) command("ACCT %s", ap);
1684*7c478bd9Sstevel@tonic-gate }
1685*7c478bd9Sstevel@tonic-gate 
1686*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1687*7c478bd9Sstevel@tonic-gate static void
1688*7c478bd9Sstevel@tonic-gate proxabort(int sig)
1689*7c478bd9Sstevel@tonic-gate {
1690*7c478bd9Sstevel@tonic-gate 	extern int proxy;
1691*7c478bd9Sstevel@tonic-gate 
1692*7c478bd9Sstevel@tonic-gate 	if (!proxy) {
1693*7c478bd9Sstevel@tonic-gate 		pswitch(1);
1694*7c478bd9Sstevel@tonic-gate 	}
1695*7c478bd9Sstevel@tonic-gate 	if (connected) {
1696*7c478bd9Sstevel@tonic-gate 		proxflag = 1;
1697*7c478bd9Sstevel@tonic-gate 	} else {
1698*7c478bd9Sstevel@tonic-gate 		proxflag = 0;
1699*7c478bd9Sstevel@tonic-gate 	}
1700*7c478bd9Sstevel@tonic-gate 	pswitch(0);
1701*7c478bd9Sstevel@tonic-gate 	longjmp(abortprox, 1);
1702*7c478bd9Sstevel@tonic-gate }
1703*7c478bd9Sstevel@tonic-gate 
1704*7c478bd9Sstevel@tonic-gate void
1705*7c478bd9Sstevel@tonic-gate doproxy(int argc, char *argv[])
1706*7c478bd9Sstevel@tonic-gate {
1707*7c478bd9Sstevel@tonic-gate 	void (*oldintr)();
1708*7c478bd9Sstevel@tonic-gate 	struct cmd *c;
1709*7c478bd9Sstevel@tonic-gate 
1710*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1711*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "command") == -1) {
1712*7c478bd9Sstevel@tonic-gate 			code = -1;
1713*7c478bd9Sstevel@tonic-gate 			return;
1714*7c478bd9Sstevel@tonic-gate 		}
1715*7c478bd9Sstevel@tonic-gate 		makeargv();
1716*7c478bd9Sstevel@tonic-gate 		argc = margc;
1717*7c478bd9Sstevel@tonic-gate 		argv = margv;
1718*7c478bd9Sstevel@tonic-gate 	}
1719*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
1720*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s command\n", argv[0]);
1721*7c478bd9Sstevel@tonic-gate 		code = -1;
1722*7c478bd9Sstevel@tonic-gate 		return;
1723*7c478bd9Sstevel@tonic-gate 	}
1724*7c478bd9Sstevel@tonic-gate 	c = getcmd(argv[1]);
1725*7c478bd9Sstevel@tonic-gate 	if (c == (struct cmd *)-1) {
1726*7c478bd9Sstevel@tonic-gate 		(void) printf("?Ambiguous command\n");
1727*7c478bd9Sstevel@tonic-gate 		(void) fflush(stdout);
1728*7c478bd9Sstevel@tonic-gate 		code = -1;
1729*7c478bd9Sstevel@tonic-gate 		return;
1730*7c478bd9Sstevel@tonic-gate 	}
1731*7c478bd9Sstevel@tonic-gate 	if (c == 0) {
1732*7c478bd9Sstevel@tonic-gate 		(void) printf("?Invalid command\n");
1733*7c478bd9Sstevel@tonic-gate 		(void) fflush(stdout);
1734*7c478bd9Sstevel@tonic-gate 		code = -1;
1735*7c478bd9Sstevel@tonic-gate 		return;
1736*7c478bd9Sstevel@tonic-gate 	}
1737*7c478bd9Sstevel@tonic-gate 	if (!c->c_proxy) {
1738*7c478bd9Sstevel@tonic-gate 		(void) printf("?Invalid proxy command\n");
1739*7c478bd9Sstevel@tonic-gate 		(void) fflush(stdout);
1740*7c478bd9Sstevel@tonic-gate 		code = -1;
1741*7c478bd9Sstevel@tonic-gate 		return;
1742*7c478bd9Sstevel@tonic-gate 	}
1743*7c478bd9Sstevel@tonic-gate 	if (setjmp(abortprox)) {
1744*7c478bd9Sstevel@tonic-gate 		code = -1;
1745*7c478bd9Sstevel@tonic-gate 		return;
1746*7c478bd9Sstevel@tonic-gate 	}
1747*7c478bd9Sstevel@tonic-gate 	oldintr = signal(SIGINT, (void (*)())proxabort);
1748*7c478bd9Sstevel@tonic-gate 	pswitch(1);
1749*7c478bd9Sstevel@tonic-gate 	if (c->c_conn && !connected) {
1750*7c478bd9Sstevel@tonic-gate 		(void) printf("Not connected\n");
1751*7c478bd9Sstevel@tonic-gate 		(void) fflush(stdout);
1752*7c478bd9Sstevel@tonic-gate 		pswitch(0);
1753*7c478bd9Sstevel@tonic-gate 		(void) signal(SIGINT, oldintr);
1754*7c478bd9Sstevel@tonic-gate 		code = -1;
1755*7c478bd9Sstevel@tonic-gate 		return;
1756*7c478bd9Sstevel@tonic-gate 	}
1757*7c478bd9Sstevel@tonic-gate 	(*c->c_handler)(argc-1, argv+1);
1758*7c478bd9Sstevel@tonic-gate 	if (connected) {
1759*7c478bd9Sstevel@tonic-gate 		proxflag = 1;
1760*7c478bd9Sstevel@tonic-gate 	} else {
1761*7c478bd9Sstevel@tonic-gate 		proxflag = 0;
1762*7c478bd9Sstevel@tonic-gate 	}
1763*7c478bd9Sstevel@tonic-gate 	pswitch(0);
1764*7c478bd9Sstevel@tonic-gate 	(void) signal(SIGINT, oldintr);
1765*7c478bd9Sstevel@tonic-gate }
1766*7c478bd9Sstevel@tonic-gate 
1767*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1768*7c478bd9Sstevel@tonic-gate void
1769*7c478bd9Sstevel@tonic-gate setcase(int argc, char *argv[])
1770*7c478bd9Sstevel@tonic-gate {
1771*7c478bd9Sstevel@tonic-gate 	mcase = !mcase;
1772*7c478bd9Sstevel@tonic-gate 	(void) printf("Case mapping %s.\n", onoff(mcase));
1773*7c478bd9Sstevel@tonic-gate 	code = mcase;
1774*7c478bd9Sstevel@tonic-gate }
1775*7c478bd9Sstevel@tonic-gate 
1776*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1777*7c478bd9Sstevel@tonic-gate void
1778*7c478bd9Sstevel@tonic-gate setcr(int argc, char *argv[])
1779*7c478bd9Sstevel@tonic-gate {
1780*7c478bd9Sstevel@tonic-gate 	crflag = !crflag;
1781*7c478bd9Sstevel@tonic-gate 	(void) printf("Carriage Return stripping %s.\n", onoff(crflag));
1782*7c478bd9Sstevel@tonic-gate 	code = crflag;
1783*7c478bd9Sstevel@tonic-gate }
1784*7c478bd9Sstevel@tonic-gate 
1785*7c478bd9Sstevel@tonic-gate void
1786*7c478bd9Sstevel@tonic-gate setntrans(int argc, char *argv[])
1787*7c478bd9Sstevel@tonic-gate {
1788*7c478bd9Sstevel@tonic-gate 	if (argc == 1) {
1789*7c478bd9Sstevel@tonic-gate 		ntflag = 0;
1790*7c478bd9Sstevel@tonic-gate 		(void) printf("Ntrans off.\n");
1791*7c478bd9Sstevel@tonic-gate 		code = ntflag;
1792*7c478bd9Sstevel@tonic-gate 		return;
1793*7c478bd9Sstevel@tonic-gate 	}
1794*7c478bd9Sstevel@tonic-gate 	ntflag++;
1795*7c478bd9Sstevel@tonic-gate 	code = ntflag;
1796*7c478bd9Sstevel@tonic-gate 	(void) strncpy(ntin, argv[1], 16);
1797*7c478bd9Sstevel@tonic-gate 	ntin[16] = '\0';
1798*7c478bd9Sstevel@tonic-gate 	if (argc == 2) {
1799*7c478bd9Sstevel@tonic-gate 		ntout[0] = '\0';
1800*7c478bd9Sstevel@tonic-gate 		return;
1801*7c478bd9Sstevel@tonic-gate 	}
1802*7c478bd9Sstevel@tonic-gate 	(void) strncpy(ntout, argv[2], 16);
1803*7c478bd9Sstevel@tonic-gate 	ntout[16] = '\0';
1804*7c478bd9Sstevel@tonic-gate }
1805*7c478bd9Sstevel@tonic-gate 
1806*7c478bd9Sstevel@tonic-gate static char *
1807*7c478bd9Sstevel@tonic-gate dotrans(char *name)
1808*7c478bd9Sstevel@tonic-gate {
1809*7c478bd9Sstevel@tonic-gate 	static char new[MAXPATHLEN];
1810*7c478bd9Sstevel@tonic-gate 	char *cp1, *cp2 = new;
1811*7c478bd9Sstevel@tonic-gate 	int i, ostop, found;
1812*7c478bd9Sstevel@tonic-gate 
1813*7c478bd9Sstevel@tonic-gate 	for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++)
1814*7c478bd9Sstevel@tonic-gate 		;
1815*7c478bd9Sstevel@tonic-gate 	for (cp1 = name; *cp1; cp1++) {
1816*7c478bd9Sstevel@tonic-gate 		found = 0;
1817*7c478bd9Sstevel@tonic-gate 		for (i = 0; *(ntin + i) && i < 16; i++) {
1818*7c478bd9Sstevel@tonic-gate 			if (*cp1 == *(ntin + i)) {
1819*7c478bd9Sstevel@tonic-gate 				found++;
1820*7c478bd9Sstevel@tonic-gate 				if (i < ostop) {
1821*7c478bd9Sstevel@tonic-gate 					*cp2++ = *(ntout + i);
1822*7c478bd9Sstevel@tonic-gate 				}
1823*7c478bd9Sstevel@tonic-gate 				break;
1824*7c478bd9Sstevel@tonic-gate 			}
1825*7c478bd9Sstevel@tonic-gate 		}
1826*7c478bd9Sstevel@tonic-gate 		if (!found) {
1827*7c478bd9Sstevel@tonic-gate 			*cp2++ = *cp1;
1828*7c478bd9Sstevel@tonic-gate 		}
1829*7c478bd9Sstevel@tonic-gate 	}
1830*7c478bd9Sstevel@tonic-gate 	*cp2 = '\0';
1831*7c478bd9Sstevel@tonic-gate 	return (new);
1832*7c478bd9Sstevel@tonic-gate }
1833*7c478bd9Sstevel@tonic-gate 
1834*7c478bd9Sstevel@tonic-gate void
1835*7c478bd9Sstevel@tonic-gate setnmap(int argc, char *argv[])
1836*7c478bd9Sstevel@tonic-gate {
1837*7c478bd9Sstevel@tonic-gate 	char *cp;
1838*7c478bd9Sstevel@tonic-gate 
1839*7c478bd9Sstevel@tonic-gate 	if (argc == 1) {
1840*7c478bd9Sstevel@tonic-gate 		mapflag = 0;
1841*7c478bd9Sstevel@tonic-gate 		(void) printf("Nmap off.\n");
1842*7c478bd9Sstevel@tonic-gate 		code = mapflag;
1843*7c478bd9Sstevel@tonic-gate 		return;
1844*7c478bd9Sstevel@tonic-gate 	}
1845*7c478bd9Sstevel@tonic-gate 	if (argc < 3) {
1846*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "mapout") == -1) {
1847*7c478bd9Sstevel@tonic-gate 			code = -1;
1848*7c478bd9Sstevel@tonic-gate 			return;
1849*7c478bd9Sstevel@tonic-gate 		}
1850*7c478bd9Sstevel@tonic-gate 		makeargv();
1851*7c478bd9Sstevel@tonic-gate 		argc = margc;
1852*7c478bd9Sstevel@tonic-gate 		argv = margv;
1853*7c478bd9Sstevel@tonic-gate 	}
1854*7c478bd9Sstevel@tonic-gate 	if (argc < 3) {
1855*7c478bd9Sstevel@tonic-gate 		(void) printf("Usage: %s [mapin mapout]\n", argv[0]);
1856*7c478bd9Sstevel@tonic-gate 		code = -1;
1857*7c478bd9Sstevel@tonic-gate 		return;
1858*7c478bd9Sstevel@tonic-gate 	}
1859*7c478bd9Sstevel@tonic-gate 	mapflag = 1;
1860*7c478bd9Sstevel@tonic-gate 	code = 1;
1861*7c478bd9Sstevel@tonic-gate 	cp = index(altarg, ' ');
1862*7c478bd9Sstevel@tonic-gate 	if (proxy) {
1863*7c478bd9Sstevel@tonic-gate 		while (*++cp == ' ')
1864*7c478bd9Sstevel@tonic-gate 			/* NULL */;
1865*7c478bd9Sstevel@tonic-gate 		altarg = cp;
1866*7c478bd9Sstevel@tonic-gate 		cp = index(altarg, ' ');
1867*7c478bd9Sstevel@tonic-gate 	}
1868*7c478bd9Sstevel@tonic-gate 	*cp = '\0';
1869*7c478bd9Sstevel@tonic-gate 	(void) strncpy(mapin, altarg, MAXPATHLEN - 1);
1870*7c478bd9Sstevel@tonic-gate 	while (*++cp == ' ')
1871*7c478bd9Sstevel@tonic-gate 		/* NULL */;
1872*7c478bd9Sstevel@tonic-gate 	(void) strncpy(mapout, cp, MAXPATHLEN - 1);
1873*7c478bd9Sstevel@tonic-gate }
1874*7c478bd9Sstevel@tonic-gate 
1875*7c478bd9Sstevel@tonic-gate static char *
1876*7c478bd9Sstevel@tonic-gate domap(char *name)
1877*7c478bd9Sstevel@tonic-gate {
1878*7c478bd9Sstevel@tonic-gate 	static char new[MAXPATHLEN];
1879*7c478bd9Sstevel@tonic-gate 	char *cp1 = name, *cp2 = mapin;
1880*7c478bd9Sstevel@tonic-gate 	char *tp[9], *te[9];
1881*7c478bd9Sstevel@tonic-gate 	int i, toks[9], toknum, match = 1;
1882*7c478bd9Sstevel@tonic-gate 	wchar_t	wc1, wc2;
1883*7c478bd9Sstevel@tonic-gate 	int	len1, len2;
1884*7c478bd9Sstevel@tonic-gate 
1885*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < 9; ++i) {
1886*7c478bd9Sstevel@tonic-gate 		toks[i] = 0;
1887*7c478bd9Sstevel@tonic-gate 	}
1888*7c478bd9Sstevel@tonic-gate 	while (match && *cp1 && *cp2) {
1889*7c478bd9Sstevel@tonic-gate 		if ((len1 = mbtowc(&wc1, cp1, MB_CUR_MAX)) <= 0) {
1890*7c478bd9Sstevel@tonic-gate 			wc1 = (unsigned char)*cp1;
1891*7c478bd9Sstevel@tonic-gate 			len1 = 1;
1892*7c478bd9Sstevel@tonic-gate 		}
1893*7c478bd9Sstevel@tonic-gate 		cp1 += len1;
1894*7c478bd9Sstevel@tonic-gate 		if ((len2 = mbtowc(&wc2, cp2, MB_CUR_MAX)) <= 0) {
1895*7c478bd9Sstevel@tonic-gate 			wc2 = (unsigned char)*cp2;
1896*7c478bd9Sstevel@tonic-gate 			len2 = 1;
1897*7c478bd9Sstevel@tonic-gate 		}
1898*7c478bd9Sstevel@tonic-gate 		cp2 += len2;
1899*7c478bd9Sstevel@tonic-gate 
1900*7c478bd9Sstevel@tonic-gate 		switch (wc2) {
1901*7c478bd9Sstevel@tonic-gate 		case '\\':
1902*7c478bd9Sstevel@tonic-gate 			if ((len2 = mbtowc(&wc2, cp2, MB_CUR_MAX)) <= 0) {
1903*7c478bd9Sstevel@tonic-gate 				wc2 = (unsigned char)*cp2;
1904*7c478bd9Sstevel@tonic-gate 				len2 = 1;
1905*7c478bd9Sstevel@tonic-gate 			}
1906*7c478bd9Sstevel@tonic-gate 			cp2 += len2;
1907*7c478bd9Sstevel@tonic-gate 			if (wc2 != wc1)
1908*7c478bd9Sstevel@tonic-gate 				match = 0;
1909*7c478bd9Sstevel@tonic-gate 			break;
1910*7c478bd9Sstevel@tonic-gate 
1911*7c478bd9Sstevel@tonic-gate 		case '$':
1912*7c478bd9Sstevel@tonic-gate 			if (*cp2 >= '1' && *cp2 <= '9') {
1913*7c478bd9Sstevel@tonic-gate 				if ((len2 =
1914*7c478bd9Sstevel@tonic-gate 				    mbtowc(&wc2, cp2 + 1, MB_CUR_MAX)) <= 0) {
1915*7c478bd9Sstevel@tonic-gate 					wc2 = (unsigned char)*(cp2 + 1);
1916*7c478bd9Sstevel@tonic-gate 					len2 = 1;
1917*7c478bd9Sstevel@tonic-gate 				}
1918*7c478bd9Sstevel@tonic-gate 				if (wc1 != wc2) {
1919*7c478bd9Sstevel@tonic-gate 					toks[toknum = *cp2 - '1']++;
1920*7c478bd9Sstevel@tonic-gate 					tp[toknum] = cp1 - len1;
1921*7c478bd9Sstevel@tonic-gate 					while (*cp1) {
1922*7c478bd9Sstevel@tonic-gate 						if ((len1 = mbtowc(&wc1,
1923*7c478bd9Sstevel@tonic-gate 						    cp1, MB_CUR_MAX)) <= 0) {
1924*7c478bd9Sstevel@tonic-gate 							wc1 =
1925*7c478bd9Sstevel@tonic-gate 							    (unsigned char)*cp1;
1926*7c478bd9Sstevel@tonic-gate 							len1 = 1;
1927*7c478bd9Sstevel@tonic-gate 						}
1928*7c478bd9Sstevel@tonic-gate 						cp1 += len1;
1929*7c478bd9Sstevel@tonic-gate 						if (wc2 == wc1)
1930*7c478bd9Sstevel@tonic-gate 							break;
1931*7c478bd9Sstevel@tonic-gate 					}
1932*7c478bd9Sstevel@tonic-gate 					if (*cp1 == 0 && wc2 != wc1)
1933*7c478bd9Sstevel@tonic-gate 						te[toknum] = cp1;
1934*7c478bd9Sstevel@tonic-gate 					else
1935*7c478bd9Sstevel@tonic-gate 						te[toknum] = cp1 - len1;
1936*7c478bd9Sstevel@tonic-gate 				}
1937*7c478bd9Sstevel@tonic-gate 				cp2++;			/* Consume the digit */
1938*7c478bd9Sstevel@tonic-gate 				if (wc2)
1939*7c478bd9Sstevel@tonic-gate 					cp2 += len2;	/* Consume wide char */
1940*7c478bd9Sstevel@tonic-gate 				break;
1941*7c478bd9Sstevel@tonic-gate 			}
1942*7c478bd9Sstevel@tonic-gate 			/* intentional drop through */
1943*7c478bd9Sstevel@tonic-gate 		default:
1944*7c478bd9Sstevel@tonic-gate 			if (wc2 != wc1)
1945*7c478bd9Sstevel@tonic-gate 				match = 0;
1946*7c478bd9Sstevel@tonic-gate 			break;
1947*7c478bd9Sstevel@tonic-gate 		}
1948*7c478bd9Sstevel@tonic-gate 	}
1949*7c478bd9Sstevel@tonic-gate 
1950*7c478bd9Sstevel@tonic-gate 	cp1 = new;
1951*7c478bd9Sstevel@tonic-gate 	*cp1 = '\0';
1952*7c478bd9Sstevel@tonic-gate 	cp2 = mapout;
1953*7c478bd9Sstevel@tonic-gate 	while (*cp2) {
1954*7c478bd9Sstevel@tonic-gate 		match = 0;
1955*7c478bd9Sstevel@tonic-gate 		switch (*cp2) {
1956*7c478bd9Sstevel@tonic-gate 		case '\\':
1957*7c478bd9Sstevel@tonic-gate 			cp2++;
1958*7c478bd9Sstevel@tonic-gate 			if (*cp2) {
1959*7c478bd9Sstevel@tonic-gate 				if ((len2 = mblen(cp2, MB_CUR_MAX)) <= 0)
1960*7c478bd9Sstevel@tonic-gate 					len2 = 1;
1961*7c478bd9Sstevel@tonic-gate 				memcpy(cp1, cp2, len2);
1962*7c478bd9Sstevel@tonic-gate 				cp1 += len2;
1963*7c478bd9Sstevel@tonic-gate 				cp2 += len2;
1964*7c478bd9Sstevel@tonic-gate 			}
1965*7c478bd9Sstevel@tonic-gate 			break;
1966*7c478bd9Sstevel@tonic-gate 
1967*7c478bd9Sstevel@tonic-gate 		case '[':
1968*7c478bd9Sstevel@tonic-gate LOOP:
1969*7c478bd9Sstevel@tonic-gate 			cp2++;
1970*7c478bd9Sstevel@tonic-gate 			if (*cp2 == '$' && isdigit(*(cp2+1))) {
1971*7c478bd9Sstevel@tonic-gate 				if (*++cp2 == '0') {
1972*7c478bd9Sstevel@tonic-gate 					char *cp3 = name;
1973*7c478bd9Sstevel@tonic-gate 
1974*7c478bd9Sstevel@tonic-gate 					while (*cp3) {
1975*7c478bd9Sstevel@tonic-gate 						*cp1++ = *cp3++;
1976*7c478bd9Sstevel@tonic-gate 					}
1977*7c478bd9Sstevel@tonic-gate 					match = 1;
1978*7c478bd9Sstevel@tonic-gate 				} else if (toks[toknum = *cp2 - '1']) {
1979*7c478bd9Sstevel@tonic-gate 					char *cp3 = tp[toknum];
1980*7c478bd9Sstevel@tonic-gate 
1981*7c478bd9Sstevel@tonic-gate 					while (cp3 != te[toknum]) {
1982*7c478bd9Sstevel@tonic-gate 						*cp1++ = *cp3++;
1983*7c478bd9Sstevel@tonic-gate 					}
1984*7c478bd9Sstevel@tonic-gate 					match = 1;
1985*7c478bd9Sstevel@tonic-gate 				}
1986*7c478bd9Sstevel@tonic-gate 			} else {
1987*7c478bd9Sstevel@tonic-gate 				while (*cp2 && *cp2 != ',' && *cp2 != ']') {
1988*7c478bd9Sstevel@tonic-gate 					if (*cp2 == '\\') {
1989*7c478bd9Sstevel@tonic-gate 						cp2++;
1990*7c478bd9Sstevel@tonic-gate 						continue;
1991*7c478bd9Sstevel@tonic-gate 					}
1992*7c478bd9Sstevel@tonic-gate 
1993*7c478bd9Sstevel@tonic-gate 					if (*cp2 == '$' && isdigit(*(cp2+1))) {
1994*7c478bd9Sstevel@tonic-gate 						if (*++cp2 == '0') {
1995*7c478bd9Sstevel@tonic-gate 							char *cp3 = name;
1996*7c478bd9Sstevel@tonic-gate 
1997*7c478bd9Sstevel@tonic-gate 							while (*cp3)
1998*7c478bd9Sstevel@tonic-gate 								*cp1++ = *cp3++;
1999*7c478bd9Sstevel@tonic-gate 							continue;
2000*7c478bd9Sstevel@tonic-gate 						}
2001*7c478bd9Sstevel@tonic-gate 						if (toks[toknum = *cp2 - '1']) {
2002*7c478bd9Sstevel@tonic-gate 							char *cp3 = tp[toknum];
2003*7c478bd9Sstevel@tonic-gate 
2004*7c478bd9Sstevel@tonic-gate 							while (cp3 !=
2005*7c478bd9Sstevel@tonic-gate 							    te[toknum])
2006*7c478bd9Sstevel@tonic-gate 								*cp1++ = *cp3++;
2007*7c478bd9Sstevel@tonic-gate 						}
2008*7c478bd9Sstevel@tonic-gate 						continue;
2009*7c478bd9Sstevel@tonic-gate 					}
2010*7c478bd9Sstevel@tonic-gate 					if (*cp2) {
2011*7c478bd9Sstevel@tonic-gate 						if ((len2 =
2012*7c478bd9Sstevel@tonic-gate 						    mblen(cp2, MB_CUR_MAX)) <=
2013*7c478bd9Sstevel@tonic-gate 						    0) {
2014*7c478bd9Sstevel@tonic-gate 							len2 = 1;
2015*7c478bd9Sstevel@tonic-gate 						}
2016*7c478bd9Sstevel@tonic-gate 						memcpy(cp1, cp2, len2);
2017*7c478bd9Sstevel@tonic-gate 						cp1 += len2;
2018*7c478bd9Sstevel@tonic-gate 						cp2 += len2;
2019*7c478bd9Sstevel@tonic-gate 					}
2020*7c478bd9Sstevel@tonic-gate 				}
2021*7c478bd9Sstevel@tonic-gate 				if (!*cp2) {
2022*7c478bd9Sstevel@tonic-gate 					(void) printf(
2023*7c478bd9Sstevel@tonic-gate 						"nmap: unbalanced brackets\n");
2024*7c478bd9Sstevel@tonic-gate 					return (name);
2025*7c478bd9Sstevel@tonic-gate 				}
2026*7c478bd9Sstevel@tonic-gate 				match = 1;
2027*7c478bd9Sstevel@tonic-gate 			}
2028*7c478bd9Sstevel@tonic-gate 			if (match) {
2029*7c478bd9Sstevel@tonic-gate 				while (*cp2 && *cp2 != ']') {
2030*7c478bd9Sstevel@tonic-gate 					if (*cp2 == '\\' && *(cp2 + 1)) {
2031*7c478bd9Sstevel@tonic-gate 						cp2++;
2032*7c478bd9Sstevel@tonic-gate 					}
2033*7c478bd9Sstevel@tonic-gate 					if ((len2 = mblen(cp2, MB_CUR_MAX)) <=
2034*7c478bd9Sstevel@tonic-gate 					    0)
2035*7c478bd9Sstevel@tonic-gate 						len2 = 1;
2036*7c478bd9Sstevel@tonic-gate 					cp2 += len2;
2037*7c478bd9Sstevel@tonic-gate 				}
2038*7c478bd9Sstevel@tonic-gate 				if (!*cp2) {
2039*7c478bd9Sstevel@tonic-gate 					(void) printf(
2040*7c478bd9Sstevel@tonic-gate 						"nmap: unbalanced brackets\n");
2041*7c478bd9Sstevel@tonic-gate 					return (name);
2042*7c478bd9Sstevel@tonic-gate 				}
2043*7c478bd9Sstevel@tonic-gate 				cp2++;
2044*7c478bd9Sstevel@tonic-gate 				break;
2045*7c478bd9Sstevel@tonic-gate 			}
2046*7c478bd9Sstevel@tonic-gate 			switch (*++cp2) {
2047*7c478bd9Sstevel@tonic-gate 				case ',':
2048*7c478bd9Sstevel@tonic-gate 					goto LOOP;
2049*7c478bd9Sstevel@tonic-gate 				case ']':
2050*7c478bd9Sstevel@tonic-gate 					break;
2051*7c478bd9Sstevel@tonic-gate 				default:
2052*7c478bd9Sstevel@tonic-gate 					cp2--;
2053*7c478bd9Sstevel@tonic-gate 					goto LOOP;
2054*7c478bd9Sstevel@tonic-gate 			}
2055*7c478bd9Sstevel@tonic-gate 			cp2++;
2056*7c478bd9Sstevel@tonic-gate 			break;
2057*7c478bd9Sstevel@tonic-gate 		case '$':
2058*7c478bd9Sstevel@tonic-gate 			if (isdigit(*(cp2 + 1))) {
2059*7c478bd9Sstevel@tonic-gate 				if (*++cp2 == '0') {
2060*7c478bd9Sstevel@tonic-gate 					char *cp3 = name;
2061*7c478bd9Sstevel@tonic-gate 
2062*7c478bd9Sstevel@tonic-gate 					while (*cp3) {
2063*7c478bd9Sstevel@tonic-gate 						*cp1++ = *cp3++;
2064*7c478bd9Sstevel@tonic-gate 					}
2065*7c478bd9Sstevel@tonic-gate 				} else if (toks[toknum = *cp2 - '1']) {
2066*7c478bd9Sstevel@tonic-gate 					char *cp3 = tp[toknum];
2067*7c478bd9Sstevel@tonic-gate 
2068*7c478bd9Sstevel@tonic-gate 					while (cp3 != te[toknum]) {
2069*7c478bd9Sstevel@tonic-gate 						*cp1++ = *cp3++;
2070*7c478bd9Sstevel@tonic-gate 					}
2071*7c478bd9Sstevel@tonic-gate 				}
2072*7c478bd9Sstevel@tonic-gate 				cp2++;
2073*7c478bd9Sstevel@tonic-gate 				break;
2074*7c478bd9Sstevel@tonic-gate 			}
2075*7c478bd9Sstevel@tonic-gate 			/* intentional drop through */
2076*7c478bd9Sstevel@tonic-gate 		default:
2077*7c478bd9Sstevel@tonic-gate 			if ((len2 = mblen(cp2, MB_CUR_MAX)) <= 0)
2078*7c478bd9Sstevel@tonic-gate 				len2 = 1;
2079*7c478bd9Sstevel@tonic-gate 			memcpy(cp1, cp2, len2);
2080*7c478bd9Sstevel@tonic-gate 			cp1 += len2;
2081*7c478bd9Sstevel@tonic-gate 			cp2 += len2;
2082*7c478bd9Sstevel@tonic-gate 			break;
2083*7c478bd9Sstevel@tonic-gate 		}
2084*7c478bd9Sstevel@tonic-gate 	}
2085*7c478bd9Sstevel@tonic-gate 	*cp1 = '\0';
2086*7c478bd9Sstevel@tonic-gate 	if (!*new) {
2087*7c478bd9Sstevel@tonic-gate 		return (name);
2088*7c478bd9Sstevel@tonic-gate 	}
2089*7c478bd9Sstevel@tonic-gate 	return (new);
2090*7c478bd9Sstevel@tonic-gate }
2091*7c478bd9Sstevel@tonic-gate 
2092*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2093*7c478bd9Sstevel@tonic-gate void
2094*7c478bd9Sstevel@tonic-gate setsunique(int argc, char *argv[])
2095*7c478bd9Sstevel@tonic-gate {
2096*7c478bd9Sstevel@tonic-gate 	sunique = !sunique;
2097*7c478bd9Sstevel@tonic-gate 	(void) printf("Store unique %s.\n", onoff(sunique));
2098*7c478bd9Sstevel@tonic-gate 	code = sunique;
2099*7c478bd9Sstevel@tonic-gate }
2100*7c478bd9Sstevel@tonic-gate 
2101*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2102*7c478bd9Sstevel@tonic-gate void
2103*7c478bd9Sstevel@tonic-gate setrunique(int argc, char *argv[])
2104*7c478bd9Sstevel@tonic-gate {
2105*7c478bd9Sstevel@tonic-gate 	runique = !runique;
2106*7c478bd9Sstevel@tonic-gate 	(void) printf("Receive unique %s.\n", onoff(runique));
2107*7c478bd9Sstevel@tonic-gate 	code = runique;
2108*7c478bd9Sstevel@tonic-gate }
2109*7c478bd9Sstevel@tonic-gate 
2110*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2111*7c478bd9Sstevel@tonic-gate void
2112*7c478bd9Sstevel@tonic-gate setpassive(int argc, char *argv[])
2113*7c478bd9Sstevel@tonic-gate {
2114*7c478bd9Sstevel@tonic-gate 	passivemode = !passivemode;
2115*7c478bd9Sstevel@tonic-gate 	(void) printf("Passive mode %s.\n", onoff(passivemode));
2116*7c478bd9Sstevel@tonic-gate 	code = passivemode;
2117*7c478bd9Sstevel@tonic-gate }
2118*7c478bd9Sstevel@tonic-gate 
2119*7c478bd9Sstevel@tonic-gate void
2120*7c478bd9Sstevel@tonic-gate settcpwindow(int argc, char *argv[])
2121*7c478bd9Sstevel@tonic-gate {
2122*7c478bd9Sstevel@tonic-gate 	int owindowsize = tcpwindowsize;
2123*7c478bd9Sstevel@tonic-gate 
2124*7c478bd9Sstevel@tonic-gate 	if (argc > 2) {
2125*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s [size]\n", argv[0]);
2126*7c478bd9Sstevel@tonic-gate 		code = -1;
2127*7c478bd9Sstevel@tonic-gate 		return;
2128*7c478bd9Sstevel@tonic-gate 	}
2129*7c478bd9Sstevel@tonic-gate 	if (argc == 2) {
2130*7c478bd9Sstevel@tonic-gate 		int window;
2131*7c478bd9Sstevel@tonic-gate 		char *endp;
2132*7c478bd9Sstevel@tonic-gate 
2133*7c478bd9Sstevel@tonic-gate 		errno = 0;
2134*7c478bd9Sstevel@tonic-gate 		window = (int)strtol(argv[1], &endp, 10);
2135*7c478bd9Sstevel@tonic-gate 		if (errno || window < 0 || *endp != '\0')
2136*7c478bd9Sstevel@tonic-gate 			(void) printf("%s: Invalid size `%s'\n",
2137*7c478bd9Sstevel@tonic-gate 				argv[0], argv[1]);
2138*7c478bd9Sstevel@tonic-gate 		else
2139*7c478bd9Sstevel@tonic-gate 			tcpwindowsize = window;
2140*7c478bd9Sstevel@tonic-gate 	}
2141*7c478bd9Sstevel@tonic-gate 	if (tcpwindowsize == 0) {
2142*7c478bd9Sstevel@tonic-gate 		if (owindowsize == 0)
2143*7c478bd9Sstevel@tonic-gate 			(void) printf("No TCP window size defined\n");
2144*7c478bd9Sstevel@tonic-gate 		else
2145*7c478bd9Sstevel@tonic-gate 			(void) printf("TCP window size cleared\n");
2146*7c478bd9Sstevel@tonic-gate 	} else
2147*7c478bd9Sstevel@tonic-gate 		(void) printf("TCP window size is set to %d\n", tcpwindowsize);
2148*7c478bd9Sstevel@tonic-gate }
2149*7c478bd9Sstevel@tonic-gate 
2150*7c478bd9Sstevel@tonic-gate /* change directory to parent directory */
2151*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2152*7c478bd9Sstevel@tonic-gate void
2153*7c478bd9Sstevel@tonic-gate cdup(int argc, char *argv[])
2154*7c478bd9Sstevel@tonic-gate {
2155*7c478bd9Sstevel@tonic-gate 	(void) command("CDUP");
2156*7c478bd9Sstevel@tonic-gate }
2157*7c478bd9Sstevel@tonic-gate 
2158*7c478bd9Sstevel@tonic-gate void
2159*7c478bd9Sstevel@tonic-gate macdef(int argc, char *argv[])
2160*7c478bd9Sstevel@tonic-gate {
2161*7c478bd9Sstevel@tonic-gate 	char *tmp;
2162*7c478bd9Sstevel@tonic-gate 	int c;
2163*7c478bd9Sstevel@tonic-gate 
2164*7c478bd9Sstevel@tonic-gate 	if (macnum == 16) {
2165*7c478bd9Sstevel@tonic-gate 		(void) printf("Limit of 16 macros have already been defined\n");
2166*7c478bd9Sstevel@tonic-gate 		code = -1;
2167*7c478bd9Sstevel@tonic-gate 		return;
2168*7c478bd9Sstevel@tonic-gate 	}
2169*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
2170*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "macro name") == -1) {
2171*7c478bd9Sstevel@tonic-gate 			code = -1;
2172*7c478bd9Sstevel@tonic-gate 			return;
2173*7c478bd9Sstevel@tonic-gate 		}
2174*7c478bd9Sstevel@tonic-gate 		makeargv();
2175*7c478bd9Sstevel@tonic-gate 		argc = margc;
2176*7c478bd9Sstevel@tonic-gate 		argv = margv;
2177*7c478bd9Sstevel@tonic-gate 	}
2178*7c478bd9Sstevel@tonic-gate 	if (argc != 2) {
2179*7c478bd9Sstevel@tonic-gate 		(void) printf("Usage: %s macro_name\n", argv[0]);
2180*7c478bd9Sstevel@tonic-gate 		code = -1;
2181*7c478bd9Sstevel@tonic-gate 		return;
2182*7c478bd9Sstevel@tonic-gate 	}
2183*7c478bd9Sstevel@tonic-gate 	if (interactive) {
2184*7c478bd9Sstevel@tonic-gate 		(void) printf("Enter macro line by line, terminating "
2185*7c478bd9Sstevel@tonic-gate 		    "it with a null line\n");
2186*7c478bd9Sstevel@tonic-gate 	}
2187*7c478bd9Sstevel@tonic-gate 	(void) strncpy(macros[macnum].mac_name, argv[1], 8);
2188*7c478bd9Sstevel@tonic-gate 	if (macnum == 0) {
2189*7c478bd9Sstevel@tonic-gate 		macros[macnum].mac_start = macbuf;
2190*7c478bd9Sstevel@tonic-gate 	} else {
2191*7c478bd9Sstevel@tonic-gate 		macros[macnum].mac_start = macros[macnum - 1].mac_end + 1;
2192*7c478bd9Sstevel@tonic-gate 	}
2193*7c478bd9Sstevel@tonic-gate 	tmp = macros[macnum].mac_start;
2194*7c478bd9Sstevel@tonic-gate 	while (tmp != macbuf+4096) {
2195*7c478bd9Sstevel@tonic-gate 		if ((c = getchar()) == EOF) {
2196*7c478bd9Sstevel@tonic-gate 			(void) printf("macdef:end of file encountered\n");
2197*7c478bd9Sstevel@tonic-gate 			code = -1;
2198*7c478bd9Sstevel@tonic-gate 			return;
2199*7c478bd9Sstevel@tonic-gate 		}
2200*7c478bd9Sstevel@tonic-gate 		if ((*tmp = c) == '\n') {
2201*7c478bd9Sstevel@tonic-gate 			if (tmp == macros[macnum].mac_start) {
2202*7c478bd9Sstevel@tonic-gate 				macros[macnum++].mac_end = tmp;
2203*7c478bd9Sstevel@tonic-gate 				code = 0;
2204*7c478bd9Sstevel@tonic-gate 				return;
2205*7c478bd9Sstevel@tonic-gate 			}
2206*7c478bd9Sstevel@tonic-gate 			if (*(tmp-1) == '\0') {
2207*7c478bd9Sstevel@tonic-gate 				macros[macnum++].mac_end = tmp - 1;
2208*7c478bd9Sstevel@tonic-gate 				code = 0;
2209*7c478bd9Sstevel@tonic-gate 				return;
2210*7c478bd9Sstevel@tonic-gate 			}
2211*7c478bd9Sstevel@tonic-gate 			*tmp = '\0';
2212*7c478bd9Sstevel@tonic-gate 		}
2213*7c478bd9Sstevel@tonic-gate 		tmp++;
2214*7c478bd9Sstevel@tonic-gate 	}
2215*7c478bd9Sstevel@tonic-gate 	for (;;) {
2216*7c478bd9Sstevel@tonic-gate 		while ((c = getchar()) != '\n' && c != EOF)
2217*7c478bd9Sstevel@tonic-gate 			/* NULL */;
2218*7c478bd9Sstevel@tonic-gate 		if (c == EOF || getchar() == '\n') {
2219*7c478bd9Sstevel@tonic-gate 			(void) printf(
2220*7c478bd9Sstevel@tonic-gate 				"Macro not defined - 4k buffer exceeded\n");
2221*7c478bd9Sstevel@tonic-gate 			code = -1;
2222*7c478bd9Sstevel@tonic-gate 			return;
2223*7c478bd9Sstevel@tonic-gate 		}
2224*7c478bd9Sstevel@tonic-gate 	}
2225*7c478bd9Sstevel@tonic-gate }
2226*7c478bd9Sstevel@tonic-gate 
2227*7c478bd9Sstevel@tonic-gate /*
2228*7c478bd9Sstevel@tonic-gate  * The p_name strings are for the getlevel and setlevel commands.
2229*7c478bd9Sstevel@tonic-gate  * The name strings for printing are in the arpa/ftp.h file in the
2230*7c478bd9Sstevel@tonic-gate  * protnames[] array of strings.
2231*7c478bd9Sstevel@tonic-gate  */
2232*7c478bd9Sstevel@tonic-gate static	struct	levels {
2233*7c478bd9Sstevel@tonic-gate 	char	*p_name;
2234*7c478bd9Sstevel@tonic-gate 	char	*p_mode;
2235*7c478bd9Sstevel@tonic-gate 	int	p_level;
2236*7c478bd9Sstevel@tonic-gate } levels[] = {
2237*7c478bd9Sstevel@tonic-gate 	{ "clear",	"C",	PROT_C },
2238*7c478bd9Sstevel@tonic-gate 	{ "safe",	"S",	PROT_S },
2239*7c478bd9Sstevel@tonic-gate 	{ "private",	"P",	PROT_P },
2240*7c478bd9Sstevel@tonic-gate 	NULL
2241*7c478bd9Sstevel@tonic-gate };
2242*7c478bd9Sstevel@tonic-gate 
2243*7c478bd9Sstevel@tonic-gate /*
2244*7c478bd9Sstevel@tonic-gate  * Return a pointer to a string which is the readable version of the
2245*7c478bd9Sstevel@tonic-gate  * protection level, or NULL if the input level is not found.
2246*7c478bd9Sstevel@tonic-gate  */
2247*7c478bd9Sstevel@tonic-gate static char *
2248*7c478bd9Sstevel@tonic-gate getlevel(int level)
2249*7c478bd9Sstevel@tonic-gate {
2250*7c478bd9Sstevel@tonic-gate 	struct levels *p;
2251*7c478bd9Sstevel@tonic-gate 
2252*7c478bd9Sstevel@tonic-gate 	for (p = levels; (p != NULL) && (p->p_level != level); p++)
2253*7c478bd9Sstevel@tonic-gate 		;
2254*7c478bd9Sstevel@tonic-gate 	return (p ? p->p_name : NULL);
2255*7c478bd9Sstevel@tonic-gate }
2256*7c478bd9Sstevel@tonic-gate 
2257*7c478bd9Sstevel@tonic-gate static char *plevel[] = {
2258*7c478bd9Sstevel@tonic-gate 	"protect",
2259*7c478bd9Sstevel@tonic-gate 	"",
2260*7c478bd9Sstevel@tonic-gate 	NULL
2261*7c478bd9Sstevel@tonic-gate };
2262*7c478bd9Sstevel@tonic-gate 
2263*7c478bd9Sstevel@tonic-gate /*
2264*7c478bd9Sstevel@tonic-gate  * Set control channel protection level.
2265*7c478bd9Sstevel@tonic-gate  */
2266*7c478bd9Sstevel@tonic-gate void
2267*7c478bd9Sstevel@tonic-gate setclevel(int argc, char *argv[])
2268*7c478bd9Sstevel@tonic-gate {
2269*7c478bd9Sstevel@tonic-gate 	struct levels *p;
2270*7c478bd9Sstevel@tonic-gate 	char *levelp;
2271*7c478bd9Sstevel@tonic-gate 	int comret;
2272*7c478bd9Sstevel@tonic-gate 
2273*7c478bd9Sstevel@tonic-gate 	if (argc > 2) {
2274*7c478bd9Sstevel@tonic-gate 		char *sep;
2275*7c478bd9Sstevel@tonic-gate 
2276*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s [", argv[0]);
2277*7c478bd9Sstevel@tonic-gate 		sep = " ";
2278*7c478bd9Sstevel@tonic-gate 		for (p = levels; p->p_name; p++) {
2279*7c478bd9Sstevel@tonic-gate 			(void) printf("%s%s", sep, p->p_name);
2280*7c478bd9Sstevel@tonic-gate 			if (*sep == ' ')
2281*7c478bd9Sstevel@tonic-gate 				sep = " | ";
2282*7c478bd9Sstevel@tonic-gate 		}
2283*7c478bd9Sstevel@tonic-gate 		(void) printf(" ]\n");
2284*7c478bd9Sstevel@tonic-gate 		code = -1;
2285*7c478bd9Sstevel@tonic-gate 		return;
2286*7c478bd9Sstevel@tonic-gate 	}
2287*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
2288*7c478bd9Sstevel@tonic-gate 		levelp = getlevel(clevel);
2289*7c478bd9Sstevel@tonic-gate 		(void) printf("Using %s protection level for commands.\n",
2290*7c478bd9Sstevel@tonic-gate 			levelp ? levelp : "<unknown>");
2291*7c478bd9Sstevel@tonic-gate 		code = 0;
2292*7c478bd9Sstevel@tonic-gate 		return;
2293*7c478bd9Sstevel@tonic-gate 	}
2294*7c478bd9Sstevel@tonic-gate 	for (p = levels; (p != NULL) && (p->p_name); p++)
2295*7c478bd9Sstevel@tonic-gate 		if (strcmp(argv[1], p->p_name) == 0)
2296*7c478bd9Sstevel@tonic-gate 			break;
2297*7c478bd9Sstevel@tonic-gate 	if (p->p_name == 0) {
2298*7c478bd9Sstevel@tonic-gate 		(void) printf("%s: unknown protection level\n", argv[1]);
2299*7c478bd9Sstevel@tonic-gate 		code = -1;
2300*7c478bd9Sstevel@tonic-gate 		return;
2301*7c478bd9Sstevel@tonic-gate 	}
2302*7c478bd9Sstevel@tonic-gate 	if (auth_type == AUTHTYPE_NONE) {
2303*7c478bd9Sstevel@tonic-gate 		if (strcmp(p->p_name, "clear"))
2304*7c478bd9Sstevel@tonic-gate 			(void) printf("Cannot set protection level to %s\n",
2305*7c478bd9Sstevel@tonic-gate 				argv[1]);
2306*7c478bd9Sstevel@tonic-gate 		return;
2307*7c478bd9Sstevel@tonic-gate 	}
2308*7c478bd9Sstevel@tonic-gate 	if (strcmp(p->p_name, "clear") == 0) {
2309*7c478bd9Sstevel@tonic-gate 		comret = command("CCC");
2310*7c478bd9Sstevel@tonic-gate 		if (comret == COMPLETE)
2311*7c478bd9Sstevel@tonic-gate 			clevel = PROT_C;
2312*7c478bd9Sstevel@tonic-gate 		return;
2313*7c478bd9Sstevel@tonic-gate 	}
2314*7c478bd9Sstevel@tonic-gate 	clevel = p->p_level;
2315*7c478bd9Sstevel@tonic-gate 	(void) printf("Control channel protection level set to %s.\n",
2316*7c478bd9Sstevel@tonic-gate 		p->p_name);
2317*7c478bd9Sstevel@tonic-gate }
2318*7c478bd9Sstevel@tonic-gate 
2319*7c478bd9Sstevel@tonic-gate /*
2320*7c478bd9Sstevel@tonic-gate  * Set data channel protection level.
2321*7c478bd9Sstevel@tonic-gate  */
2322*7c478bd9Sstevel@tonic-gate void
2323*7c478bd9Sstevel@tonic-gate setdlevel(int argc, char *argv[])
2324*7c478bd9Sstevel@tonic-gate {
2325*7c478bd9Sstevel@tonic-gate 	struct levels *p;
2326*7c478bd9Sstevel@tonic-gate 	int comret;
2327*7c478bd9Sstevel@tonic-gate 
2328*7c478bd9Sstevel@tonic-gate 	if (argc != 2) {
2329*7c478bd9Sstevel@tonic-gate 		char *sep;
2330*7c478bd9Sstevel@tonic-gate 
2331*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s [", argv[0]);
2332*7c478bd9Sstevel@tonic-gate 		sep = " ";
2333*7c478bd9Sstevel@tonic-gate 		for (p = levels; p->p_name; p++) {
2334*7c478bd9Sstevel@tonic-gate 			(void) printf("%s%s", sep, p->p_name);
2335*7c478bd9Sstevel@tonic-gate 			if (*sep == ' ')
2336*7c478bd9Sstevel@tonic-gate 				sep = " | ";
2337*7c478bd9Sstevel@tonic-gate 		}
2338*7c478bd9Sstevel@tonic-gate 		(void) printf(" ]\n");
2339*7c478bd9Sstevel@tonic-gate 		code = -1;
2340*7c478bd9Sstevel@tonic-gate 		return;
2341*7c478bd9Sstevel@tonic-gate 	}
2342*7c478bd9Sstevel@tonic-gate 	for (p = levels; p->p_name; p++)
2343*7c478bd9Sstevel@tonic-gate 		if (strcmp(argv[1], p->p_name) == 0)
2344*7c478bd9Sstevel@tonic-gate 			break;
2345*7c478bd9Sstevel@tonic-gate 	if (p->p_name == 0) {
2346*7c478bd9Sstevel@tonic-gate 		(void) printf("%s: unknown protection level\n", argv[1]);
2347*7c478bd9Sstevel@tonic-gate 		code = -1;
2348*7c478bd9Sstevel@tonic-gate 		return;
2349*7c478bd9Sstevel@tonic-gate 	}
2350*7c478bd9Sstevel@tonic-gate 	if (auth_type == AUTHTYPE_NONE) {
2351*7c478bd9Sstevel@tonic-gate 		if (strcmp(p->p_name, "clear"))
2352*7c478bd9Sstevel@tonic-gate 			(void) printf("Cannot set protection level to %s\n",
2353*7c478bd9Sstevel@tonic-gate 				argv[1]);
2354*7c478bd9Sstevel@tonic-gate 		return;
2355*7c478bd9Sstevel@tonic-gate 	}
2356*7c478bd9Sstevel@tonic-gate 	/* Start with a PBSZ of 1 meg */
2357*7c478bd9Sstevel@tonic-gate 	if (p->p_level != PROT_C)
2358*7c478bd9Sstevel@tonic-gate 		setpbsz(1<<20);
2359*7c478bd9Sstevel@tonic-gate 	comret = command("PROT %s", p->p_mode);
2360*7c478bd9Sstevel@tonic-gate 	if (comret == COMPLETE)
2361*7c478bd9Sstevel@tonic-gate 		dlevel = p->p_level;
2362*7c478bd9Sstevel@tonic-gate }
2363*7c478bd9Sstevel@tonic-gate 
2364*7c478bd9Sstevel@tonic-gate /*
2365*7c478bd9Sstevel@tonic-gate  * Set clear command protection level.
2366*7c478bd9Sstevel@tonic-gate  */
2367*7c478bd9Sstevel@tonic-gate /* VARARGS */
2368*7c478bd9Sstevel@tonic-gate void
2369*7c478bd9Sstevel@tonic-gate ccc(int argc, char *argv[])
2370*7c478bd9Sstevel@tonic-gate {
2371*7c478bd9Sstevel@tonic-gate 	plevel[1] = "clear";
2372*7c478bd9Sstevel@tonic-gate 	setclevel(2, plevel);
2373*7c478bd9Sstevel@tonic-gate }
2374*7c478bd9Sstevel@tonic-gate 
2375*7c478bd9Sstevel@tonic-gate /*
2376*7c478bd9Sstevel@tonic-gate  * Set clear data protection level.
2377*7c478bd9Sstevel@tonic-gate  */
2378*7c478bd9Sstevel@tonic-gate /* VARARGS */
2379*7c478bd9Sstevel@tonic-gate void
2380*7c478bd9Sstevel@tonic-gate setclear(int argc, char *argv[])
2381*7c478bd9Sstevel@tonic-gate {
2382*7c478bd9Sstevel@tonic-gate 	plevel[1] = "clear";
2383*7c478bd9Sstevel@tonic-gate 	setdlevel(2, plevel);
2384*7c478bd9Sstevel@tonic-gate }
2385*7c478bd9Sstevel@tonic-gate 
2386*7c478bd9Sstevel@tonic-gate /*
2387*7c478bd9Sstevel@tonic-gate  * Set safe data protection level.
2388*7c478bd9Sstevel@tonic-gate  */
2389*7c478bd9Sstevel@tonic-gate /* VARARGS */
2390*7c478bd9Sstevel@tonic-gate void
2391*7c478bd9Sstevel@tonic-gate setsafe(int argc, char *argv[])
2392*7c478bd9Sstevel@tonic-gate {
2393*7c478bd9Sstevel@tonic-gate 	plevel[1] = "safe";
2394*7c478bd9Sstevel@tonic-gate 	setdlevel(2, plevel);
2395*7c478bd9Sstevel@tonic-gate }
2396*7c478bd9Sstevel@tonic-gate 
2397*7c478bd9Sstevel@tonic-gate /*
2398*7c478bd9Sstevel@tonic-gate  * Set private data protection level.
2399*7c478bd9Sstevel@tonic-gate  */
2400*7c478bd9Sstevel@tonic-gate /* VARARGS */
2401*7c478bd9Sstevel@tonic-gate void
2402*7c478bd9Sstevel@tonic-gate setprivate(int argc, char *argv[])
2403*7c478bd9Sstevel@tonic-gate {
2404*7c478bd9Sstevel@tonic-gate 	plevel[1] = "private";
2405*7c478bd9Sstevel@tonic-gate 	setdlevel(2, plevel);
2406*7c478bd9Sstevel@tonic-gate }
2407*7c478bd9Sstevel@tonic-gate 
2408*7c478bd9Sstevel@tonic-gate /*
2409*7c478bd9Sstevel@tonic-gate  * Set mechanism type
2410*7c478bd9Sstevel@tonic-gate  */
2411*7c478bd9Sstevel@tonic-gate void
2412*7c478bd9Sstevel@tonic-gate setmech(int  argc, char *argv[])
2413*7c478bd9Sstevel@tonic-gate {
2414*7c478bd9Sstevel@tonic-gate 	char	tempmech[MECH_SZ];
2415*7c478bd9Sstevel@tonic-gate 
2416*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
2417*7c478bd9Sstevel@tonic-gate 		if (prompt_for_arg(line, sizeof (line), "mech-type") == -1) {
2418*7c478bd9Sstevel@tonic-gate 			code = -1;
2419*7c478bd9Sstevel@tonic-gate 			return;
2420*7c478bd9Sstevel@tonic-gate 		}
2421*7c478bd9Sstevel@tonic-gate 		makeargv();
2422*7c478bd9Sstevel@tonic-gate 		argc = margc;
2423*7c478bd9Sstevel@tonic-gate 		argv = margv;
2424*7c478bd9Sstevel@tonic-gate 	}
2425*7c478bd9Sstevel@tonic-gate 
2426*7c478bd9Sstevel@tonic-gate 	if (argc != 2) {
2427*7c478bd9Sstevel@tonic-gate 		(void) printf("usage: %s [ mechanism type ]\n", argv[0]);
2428*7c478bd9Sstevel@tonic-gate 		code = -1;
2429*7c478bd9Sstevel@tonic-gate 		return;
2430*7c478bd9Sstevel@tonic-gate 	}
2431*7c478bd9Sstevel@tonic-gate 
2432*7c478bd9Sstevel@tonic-gate 	if ((strlcpy(tempmech, argv[1], MECH_SZ) >= MECH_SZ) ||
2433*7c478bd9Sstevel@tonic-gate 		__gss_mech_to_oid(tempmech, (gss_OID*)&mechoid) !=
2434*7c478bd9Sstevel@tonic-gate 			GSS_S_COMPLETE) {
2435*7c478bd9Sstevel@tonic-gate 		(void) printf("%s: %s: not a valid security mechanism\n",
2436*7c478bd9Sstevel@tonic-gate 			argv[0], tempmech);
2437*7c478bd9Sstevel@tonic-gate 		code = -1;
2438*7c478bd9Sstevel@tonic-gate 		return;
2439*7c478bd9Sstevel@tonic-gate 	} else {
2440*7c478bd9Sstevel@tonic-gate 		(void) strlcpy(mechstr, tempmech, MECH_SZ);
2441*7c478bd9Sstevel@tonic-gate 		(void) printf("Using %s mechanism type\n", mechstr);
2442*7c478bd9Sstevel@tonic-gate 		code = 0;
2443*7c478bd9Sstevel@tonic-gate 		return;
2444*7c478bd9Sstevel@tonic-gate 	}
2445*7c478bd9Sstevel@tonic-gate }
2446