xref: /csrg-svn/usr.bin/ftp/cmds.c (revision 10294)
1*10294Ssam #ifndef lint
2*10294Ssam static char sccsid[] = "@(#)cmds.c	4.1 (Berkeley) 01/15/83";
3*10294Ssam #endif
4*10294Ssam 
5*10294Ssam /*
6*10294Ssam  * FTP User Program -- Command Routines.
7*10294Ssam  */
8*10294Ssam #include <sys/types.h>
9*10294Ssam #include <sys/socket.h>
10*10294Ssam 
11*10294Ssam #include <signal.h>
12*10294Ssam #include <stdio.h>
13*10294Ssam #include <errno.h>
14*10294Ssam #include <netdb.h>
15*10294Ssam 
16*10294Ssam #include "ftp.h"
17*10294Ssam #include "ftp_var.h"
18*10294Ssam 
19*10294Ssam int	autologin = 1;
20*10294Ssam 
21*10294Ssam /*
22*10294Ssam  * Connect to peer server and
23*10294Ssam  * auto-login, if possible.
24*10294Ssam  */
25*10294Ssam setpeer(argc, argv)
26*10294Ssam 	int argc;
27*10294Ssam 	char *argv[];
28*10294Ssam {
29*10294Ssam 	struct hostent *host, *hookup();
30*10294Ssam 	int port;
31*10294Ssam 
32*10294Ssam 	if (connected) {
33*10294Ssam 		printf("Already connected to %s, use disconnect first.\n",
34*10294Ssam 			hostname);
35*10294Ssam 		return;
36*10294Ssam 	}
37*10294Ssam 	if (argc < 2) {
38*10294Ssam 		strcat(line, " ");
39*10294Ssam 		printf("(to) ");
40*10294Ssam 		gets(&line[strlen(line)]);
41*10294Ssam 		makeargv();
42*10294Ssam 		argc = margc;
43*10294Ssam 		argv = margv;
44*10294Ssam 	}
45*10294Ssam 	if (argc > 3) {
46*10294Ssam 		printf("usage: %s host-name [port]\n", argv[0]);
47*10294Ssam 		return;
48*10294Ssam 	}
49*10294Ssam 	port = sp->s_port;
50*10294Ssam 	if (argc > 2) {
51*10294Ssam 		port = atoi(argv[1]);
52*10294Ssam 		if (port <= 0) {
53*10294Ssam 			printf("%s: bad port number.\n", argv[1]);
54*10294Ssam 			return;
55*10294Ssam 		}
56*10294Ssam 		port = htons(port);
57*10294Ssam 	}
58*10294Ssam 	host = hookup(argv[1], port);
59*10294Ssam 	if (host) {
60*10294Ssam 		connected = 1;
61*10294Ssam 		if (autologin)
62*10294Ssam 			login(host);
63*10294Ssam 	}
64*10294Ssam }
65*10294Ssam 
66*10294Ssam struct	types {
67*10294Ssam 	char	*t_name;
68*10294Ssam 	char	*t_mode;
69*10294Ssam 	int	t_type;
70*10294Ssam } types[] = {
71*10294Ssam 	{ "ascii",	"A",	TYPE_A },
72*10294Ssam 	{ "binary",	"I",	TYPE_I },
73*10294Ssam 	{ "image",	"I",	TYPE_I },
74*10294Ssam 	{ "ebcdic",	"E",	TYPE_E },
75*10294Ssam 	{ "tenex",	"L",	TYPE_L },
76*10294Ssam 	0
77*10294Ssam };
78*10294Ssam 
79*10294Ssam /*
80*10294Ssam  * Set transfer type.
81*10294Ssam  */
82*10294Ssam settype(argc, argv)
83*10294Ssam 	char *argv[];
84*10294Ssam {
85*10294Ssam 	register struct types *p;
86*10294Ssam 
87*10294Ssam 	if (argc > 2) {
88*10294Ssam 		char *sep;
89*10294Ssam 
90*10294Ssam 		printf("usage: %s [", argv[0]);
91*10294Ssam 		sep = " ";
92*10294Ssam 		for (p = types; p->t_name; p++) {
93*10294Ssam 			printf("%s%s", sep, p->t_name);
94*10294Ssam 			if (*sep == ' ')
95*10294Ssam 				sep = " | ";
96*10294Ssam 		}
97*10294Ssam 		printf(" ]\n");
98*10294Ssam 		return;
99*10294Ssam 	}
100*10294Ssam 	if (argc < 2) {
101*10294Ssam 		printf("Using %s mode to transfer files.\n", typename);
102*10294Ssam 		return;
103*10294Ssam 	}
104*10294Ssam 	for (p = types; p->t_name; p++)
105*10294Ssam 		if (strcmp(argv[1], p->t_name) == 0)
106*10294Ssam 			break;
107*10294Ssam 	if (p->t_name == 0) {
108*10294Ssam 		printf("%s: unknown mode\n", argv[1]);
109*10294Ssam 		return;
110*10294Ssam 	}
111*10294Ssam 	if (command("TYPE %s", p->t_mode) == COMPLETE) {
112*10294Ssam 		strcpy(typename, p->t_name);
113*10294Ssam 		type = p->t_type;
114*10294Ssam 	}
115*10294Ssam }
116*10294Ssam 
117*10294Ssam /*
118*10294Ssam  * Set binary transfer type.
119*10294Ssam  */
120*10294Ssam /*VARARGS*/
121*10294Ssam setbinary()
122*10294Ssam {
123*10294Ssam 
124*10294Ssam 	call(settype, "type", "binary", 0);
125*10294Ssam }
126*10294Ssam 
127*10294Ssam /*
128*10294Ssam  * Set ascii transfer type.
129*10294Ssam  */
130*10294Ssam /*VARARGS*/
131*10294Ssam setascii()
132*10294Ssam {
133*10294Ssam 
134*10294Ssam 	call(settype, "type", "ascii", 0);
135*10294Ssam }
136*10294Ssam 
137*10294Ssam /*
138*10294Ssam  * Set tenex transfer type.
139*10294Ssam  */
140*10294Ssam /*VARARGS*/
141*10294Ssam settenex()
142*10294Ssam {
143*10294Ssam 
144*10294Ssam 	call(settype, "type", "tenex", 0);
145*10294Ssam }
146*10294Ssam 
147*10294Ssam /*
148*10294Ssam  * Set ebcdic transfer type.
149*10294Ssam  */
150*10294Ssam /*VARARGS*/
151*10294Ssam setebcdic()
152*10294Ssam {
153*10294Ssam 
154*10294Ssam 	call(settype, "type", "ebcdic", 0);
155*10294Ssam }
156*10294Ssam 
157*10294Ssam /*
158*10294Ssam  * Set file transfer mode.
159*10294Ssam  */
160*10294Ssam setmode(argc, argv)
161*10294Ssam 	char *argv[];
162*10294Ssam {
163*10294Ssam 
164*10294Ssam 	printf("We only support %s mode, sorry.\n", modename);
165*10294Ssam }
166*10294Ssam 
167*10294Ssam /*
168*10294Ssam  * Set file transfer format.
169*10294Ssam  */
170*10294Ssam setform(argc, argv)
171*10294Ssam 	char *argv[];
172*10294Ssam {
173*10294Ssam 
174*10294Ssam 	printf("We only support %s format, sorry.\n", formname);
175*10294Ssam }
176*10294Ssam 
177*10294Ssam /*
178*10294Ssam  * Set file transfer structure.
179*10294Ssam  */
180*10294Ssam setstruct(argc, argv)
181*10294Ssam 	char *argv[];
182*10294Ssam {
183*10294Ssam 
184*10294Ssam 	printf("We only support %s structure, sorry.\n", structname);
185*10294Ssam }
186*10294Ssam 
187*10294Ssam /*
188*10294Ssam  * Send a single file.
189*10294Ssam  */
190*10294Ssam put(argc, argv)
191*10294Ssam 	char *argv[];
192*10294Ssam {
193*10294Ssam 	int fd;
194*10294Ssam 	register int n, addr;
195*10294Ssam 	register char *cp, *targ;
196*10294Ssam 
197*10294Ssam 	if (!connected) {
198*10294Ssam 		printf("Not connected.\n");
199*10294Ssam 		return;
200*10294Ssam 	}
201*10294Ssam 	if (argc == 2)
202*10294Ssam 		argc++, argv[2] = argv[1];
203*10294Ssam 	if (argc < 2) {
204*10294Ssam 		strcat(line, " ");
205*10294Ssam 		printf("(local-file) ");
206*10294Ssam 		gets(&line[strlen(line)]);
207*10294Ssam 		makeargv();
208*10294Ssam 		argc = margc;
209*10294Ssam 		argv = margv;
210*10294Ssam 	}
211*10294Ssam 	if (argc < 2) {
212*10294Ssam usage:
213*10294Ssam 		printf("%s local-file remote-file\n", argv[0]);
214*10294Ssam 		return;
215*10294Ssam 	}
216*10294Ssam 	if (argc < 3) {
217*10294Ssam 		strcat(line, " ");
218*10294Ssam 		printf("(remote-file) ");
219*10294Ssam 		gets(&line[strlen(line)]);
220*10294Ssam 		makeargv();
221*10294Ssam 		argc = margc;
222*10294Ssam 		argv = margv;
223*10294Ssam 	}
224*10294Ssam 	if (argc < 3)
225*10294Ssam 		goto usage;
226*10294Ssam 	sendrequest("STOR", argv[1], argv[2]);
227*10294Ssam }
228*10294Ssam 
229*10294Ssam /*
230*10294Ssam  * Receive a single file.
231*10294Ssam  */
232*10294Ssam get(argc, argv)
233*10294Ssam 	char *argv[];
234*10294Ssam {
235*10294Ssam 	int fd;
236*10294Ssam 	register int n, addr;
237*10294Ssam 	register char *cp;
238*10294Ssam 	char *src;
239*10294Ssam 
240*10294Ssam 	if (!connected) {
241*10294Ssam 		printf("Not connected.\n");
242*10294Ssam 		return;
243*10294Ssam 	}
244*10294Ssam 	if (argc == 2)
245*10294Ssam 		argc++, argv[2] = argv[1];
246*10294Ssam 	if (argc < 2) {
247*10294Ssam 		strcat(line, " ");
248*10294Ssam 		printf("(remote-file) ");
249*10294Ssam 		gets(&line[strlen(line)]);
250*10294Ssam 		makeargv();
251*10294Ssam 		argc = margc;
252*10294Ssam 		argv = margv;
253*10294Ssam 	}
254*10294Ssam 	if (argc < 2) {
255*10294Ssam usage:
256*10294Ssam 		printf("%s remote-file local-file\n", argv[0]);
257*10294Ssam 		return;
258*10294Ssam 	}
259*10294Ssam 	if (argc < 3) {
260*10294Ssam 		strcat(line, " ");
261*10294Ssam 		printf("(local-file) ");
262*10294Ssam 		gets(&line[strlen(line)]);
263*10294Ssam 		makeargv();
264*10294Ssam 		argc = margc;
265*10294Ssam 		argv = margv;
266*10294Ssam 	}
267*10294Ssam 	if (argc < 3)
268*10294Ssam 		goto usage;
269*10294Ssam 	recvrequest("RETR", argv[2], argv[1]);
270*10294Ssam }
271*10294Ssam 
272*10294Ssam char *
273*10294Ssam onoff(bool)
274*10294Ssam 	int bool;
275*10294Ssam {
276*10294Ssam 
277*10294Ssam 	return (bool ? "on" : "off");
278*10294Ssam }
279*10294Ssam 
280*10294Ssam /*
281*10294Ssam  * Show status.
282*10294Ssam  */
283*10294Ssam status(argc, argv)
284*10294Ssam 	char *argv[];
285*10294Ssam {
286*10294Ssam 
287*10294Ssam 	if (connected)
288*10294Ssam 		printf("Connected to %s.\n", hostname);
289*10294Ssam 	else
290*10294Ssam 		printf("Not connected.\n");
291*10294Ssam 	printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n",
292*10294Ssam 		modename, typename, formname, structname);
293*10294Ssam 	printf("Verbose: %s; Bell: %s; Prompting: %s\n",
294*10294Ssam 		onoff(verbose), onoff(bell), onoff(interactive));
295*10294Ssam }
296*10294Ssam 
297*10294Ssam /*
298*10294Ssam  * Set beep on cmd completed mode.
299*10294Ssam  */
300*10294Ssam /*VARARGS*/
301*10294Ssam setbell()
302*10294Ssam {
303*10294Ssam 
304*10294Ssam 	bell = !bell;
305*10294Ssam 	printf("Bell mode %s.\n", onoff(bell));
306*10294Ssam }
307*10294Ssam 
308*10294Ssam /*
309*10294Ssam  * Turn on packet tracing.
310*10294Ssam  */
311*10294Ssam /*VARARGS*/
312*10294Ssam settrace()
313*10294Ssam {
314*10294Ssam 
315*10294Ssam 	trace = !trace;
316*10294Ssam 	printf("Packet tracing %s.\n", onoff(trace));
317*10294Ssam }
318*10294Ssam 
319*10294Ssam /*
320*10294Ssam  * Turn on printing of server echo's.
321*10294Ssam  */
322*10294Ssam /*VARARGS*/
323*10294Ssam setverbose()
324*10294Ssam {
325*10294Ssam 
326*10294Ssam 	verbose = !verbose;
327*10294Ssam 	printf("Verbose mode %s.\n", onoff(verbose));
328*10294Ssam }
329*10294Ssam 
330*10294Ssam /*
331*10294Ssam  * Turn on interactive prompting
332*10294Ssam  * during mget, mput, and mdelete.
333*10294Ssam  */
334*10294Ssam /*VARARGS*/
335*10294Ssam setprompt()
336*10294Ssam {
337*10294Ssam 
338*10294Ssam 	interactive = !interactive;
339*10294Ssam 	printf("Interactive mode %s.\n", onoff(interactive));
340*10294Ssam }
341*10294Ssam 
342*10294Ssam /*
343*10294Ssam  * Set debugging mode on/off and/or
344*10294Ssam  * set level of debugging.
345*10294Ssam  */
346*10294Ssam /*VARARGS*/
347*10294Ssam setdebug(argc, argv)
348*10294Ssam 	char *argv[];
349*10294Ssam {
350*10294Ssam 	int val;
351*10294Ssam 
352*10294Ssam 	if (argc > 1) {
353*10294Ssam 		val = atoi(argv[1]);
354*10294Ssam 		if (val < 0) {
355*10294Ssam 			printf("%s: bad debugging value.\n", argv[1]);
356*10294Ssam 			return;
357*10294Ssam 		}
358*10294Ssam 	} else
359*10294Ssam 		val = !debug;
360*10294Ssam 	debug = val;
361*10294Ssam 	if (debug)
362*10294Ssam 		options |= SO_DEBUG;
363*10294Ssam 	else
364*10294Ssam 		options &= ~SO_DEBUG;
365*10294Ssam 	printf("Debugging %s (debug=%d).\n", onoff(debug), debug);
366*10294Ssam }
367*10294Ssam 
368*10294Ssam /*
369*10294Ssam  * Set current working directory
370*10294Ssam  * on remote machine.
371*10294Ssam  */
372*10294Ssam cd(argc, argv)
373*10294Ssam 	char *argv[];
374*10294Ssam {
375*10294Ssam 
376*10294Ssam 	if (!connected) {
377*10294Ssam 		printf("Not connected.\n");
378*10294Ssam 		return;
379*10294Ssam 	}
380*10294Ssam 	if (argc < 2) {
381*10294Ssam 		strcat(line, " ");
382*10294Ssam 		printf("(remote-directory) ");
383*10294Ssam 		gets(&line[strlen(line)]);
384*10294Ssam 		makeargv();
385*10294Ssam 		argc = margc;
386*10294Ssam 		argv = margv;
387*10294Ssam 	}
388*10294Ssam 	if (argc < 2) {
389*10294Ssam 		printf("%s remote-directory\n", argv[0]);
390*10294Ssam 		return;
391*10294Ssam 	}
392*10294Ssam 	(void) command("CWD %s", argv[1]);
393*10294Ssam }
394*10294Ssam 
395*10294Ssam #include <pwd.h>
396*10294Ssam 
397*10294Ssam /*
398*10294Ssam  * Set current working directory
399*10294Ssam  * on local machine.
400*10294Ssam  */
401*10294Ssam lcd(argc, argv)
402*10294Ssam 	char *argv[];
403*10294Ssam {
404*10294Ssam 	static struct passwd *pw = NULL;
405*10294Ssam 
406*10294Ssam 	if (argc < 2) {
407*10294Ssam 		if (pw == NULL) {
408*10294Ssam 			pw = getpwnam(getlogin());
409*10294Ssam 			if (pw == NULL)
410*10294Ssam 				pw = getpwuid(getuid());
411*10294Ssam 		}
412*10294Ssam 		if (pw == NULL) {
413*10294Ssam 			printf("ftp: can't find home directory.\n");
414*10294Ssam 			return;
415*10294Ssam 		}
416*10294Ssam 		argc++, argv[1] = pw->pw_dir;
417*10294Ssam 	}
418*10294Ssam 	if (argc != 2) {
419*10294Ssam 		printf("%s local-directory\n", argv[0]);
420*10294Ssam 		return;
421*10294Ssam 	}
422*10294Ssam 	if (chdir(argv[1]) < 0)
423*10294Ssam 		perror(argv[1]);
424*10294Ssam }
425*10294Ssam 
426*10294Ssam /*
427*10294Ssam  * Delete a single file.
428*10294Ssam  */
429*10294Ssam delete(argc, argv)
430*10294Ssam 	char *argv[];
431*10294Ssam {
432*10294Ssam 
433*10294Ssam 	if (argc < 2) {
434*10294Ssam 		strcat(line, " ");
435*10294Ssam 		printf("(remote-file) ");
436*10294Ssam 		gets(&line[strlen(line)]);
437*10294Ssam 		makeargv();
438*10294Ssam 		argc = margc;
439*10294Ssam 		argv = margv;
440*10294Ssam 	}
441*10294Ssam 	if (argc < 2) {
442*10294Ssam 		printf("%s remote-file\n", argv[0]);
443*10294Ssam 		return;
444*10294Ssam 	}
445*10294Ssam 	(void) command("DELE %s", argv[1]);
446*10294Ssam }
447*10294Ssam 
448*10294Ssam /*
449*10294Ssam  * Rename a remote file.
450*10294Ssam  */
451*10294Ssam renamefile(argc, argv)
452*10294Ssam 	char *argv[];
453*10294Ssam {
454*10294Ssam 
455*10294Ssam 	if (argc < 2) {
456*10294Ssam 		strcat(line, " ");
457*10294Ssam 		printf("(from-name) ");
458*10294Ssam 		gets(&line[strlen(line)]);
459*10294Ssam 		makeargv();
460*10294Ssam 		argc = margc;
461*10294Ssam 		argv = margv;
462*10294Ssam 	}
463*10294Ssam 	if (argc < 2) {
464*10294Ssam usage:
465*10294Ssam 		printf("%s from-name to-name\n", argv[0]);
466*10294Ssam 		return;
467*10294Ssam 	}
468*10294Ssam 	if (argc < 3) {
469*10294Ssam 		strcat(line, " ");
470*10294Ssam 		printf("(to-name) ");
471*10294Ssam 		gets(&line[strlen(line)]);
472*10294Ssam 		makeargv();
473*10294Ssam 		argc = margc;
474*10294Ssam 		argv = margv;
475*10294Ssam 	}
476*10294Ssam 	if (argc < 3)
477*10294Ssam 		goto usage;
478*10294Ssam 	if (command("RNFR %s", argv[1]) == CONTINUE)
479*10294Ssam 		(void) command("RNTO %s", argv[2]);
480*10294Ssam }
481*10294Ssam 
482*10294Ssam /*
483*10294Ssam  * Get a directory listing
484*10294Ssam  * of remote files.
485*10294Ssam  */
486*10294Ssam ls(argc, argv)
487*10294Ssam 	char *argv[];
488*10294Ssam {
489*10294Ssam 	char *cmd;
490*10294Ssam 
491*10294Ssam 	if (argc < 2)
492*10294Ssam 		argc++, argv[1] = NULL;
493*10294Ssam 	if (argc < 3)
494*10294Ssam 		argc++, argv[2] = "-";
495*10294Ssam 	if (argc > 3) {
496*10294Ssam 		printf("usage: %s remote-directory local-file\n", argv[0]);
497*10294Ssam 		return;
498*10294Ssam 	}
499*10294Ssam 	cmd = argv[0][0] == 'l' ? "NLST" : "LIST";
500*10294Ssam 	recvrequest(cmd, argv[2], argv[1]);
501*10294Ssam }
502*10294Ssam 
503*10294Ssam /*
504*10294Ssam  * Do a shell escape
505*10294Ssam  */
506*10294Ssam shell(argc, argv)
507*10294Ssam 	char *argv[];
508*10294Ssam {
509*10294Ssam 
510*10294Ssam 	printf("Sorry, this function is unimplemented.\n");
511*10294Ssam }
512*10294Ssam 
513*10294Ssam /*
514*10294Ssam  * Send new user information (re-login)
515*10294Ssam  */
516*10294Ssam user(argc, argv)
517*10294Ssam 	int argc;
518*10294Ssam 	char **argv;
519*10294Ssam {
520*10294Ssam 	char acct[80], *getpass();
521*10294Ssam 	int n;
522*10294Ssam 
523*10294Ssam 	if (argc < 2) {
524*10294Ssam 		strcat(line, " ");
525*10294Ssam 		printf("(username) ");
526*10294Ssam 		gets(&line[strlen(line)]);
527*10294Ssam 		makeargv();
528*10294Ssam 		argc = margc;
529*10294Ssam 		argv = margv;
530*10294Ssam 	}
531*10294Ssam 	if (argc > 4) {
532*10294Ssam 		printf("usage: %s username [password] [account]\n", argv[0]);
533*10294Ssam 		return;
534*10294Ssam 	}
535*10294Ssam 	n = command("USER %s", argv[1]);
536*10294Ssam 	if (n == CONTINUE) {
537*10294Ssam 		if (argc < 3 )
538*10294Ssam 			argv[2] = getpass("Password: "), argc++;
539*10294Ssam 		n = command("PASS %s", argv[2]);
540*10294Ssam 	}
541*10294Ssam 	if (n == CONTINUE) {
542*10294Ssam 		if (argc < 4) {
543*10294Ssam 			printf("Account: "); (void) fflush(stdout);
544*10294Ssam 			(void) fgets(acct, sizeof(acct) - 1, stdin);
545*10294Ssam 			acct[strlen(acct) - 1] = '\0';
546*10294Ssam 			argv[3] = acct; argc++;
547*10294Ssam 		}
548*10294Ssam 		n = command("ACCT %s", acct);
549*10294Ssam 	}
550*10294Ssam 	if (n != COMPLETE) {
551*10294Ssam 		fprintf(stderr, "Login failed.\n");
552*10294Ssam 		return (0);
553*10294Ssam 	}
554*10294Ssam 	return (1);
555*10294Ssam }
556*10294Ssam 
557*10294Ssam /*
558*10294Ssam  * Print working directory.
559*10294Ssam  */
560*10294Ssam /*VARARGS*/
561*10294Ssam pwd()
562*10294Ssam {
563*10294Ssam 	if (!connected) {
564*10294Ssam 		printf("Not connected.\n");
565*10294Ssam 		return;
566*10294Ssam 	}
567*10294Ssam 	(void) command("XPWD");
568*10294Ssam }
569*10294Ssam 
570*10294Ssam /*
571*10294Ssam  * Make a directory.
572*10294Ssam  */
573*10294Ssam makedir(argc, argv)
574*10294Ssam 	char *argv[];
575*10294Ssam {
576*10294Ssam 
577*10294Ssam 	if (argc < 2) {
578*10294Ssam 		strcat(line, " ");
579*10294Ssam 		printf("(directory-name) ");
580*10294Ssam 		gets(&line[strlen(line)]);
581*10294Ssam 		makeargv();
582*10294Ssam 		argc = margc;
583*10294Ssam 		argv = margv;
584*10294Ssam 	}
585*10294Ssam 	if (argc < 2) {
586*10294Ssam 		printf("%s directory-name\n", argv[0]);
587*10294Ssam 		return;
588*10294Ssam 	}
589*10294Ssam 	(void) command("XMKD %s", argv[1]);
590*10294Ssam }
591*10294Ssam 
592*10294Ssam /*
593*10294Ssam  * Remove a directory.
594*10294Ssam  */
595*10294Ssam removedir(argc, argv)
596*10294Ssam 	char *argv[];
597*10294Ssam {
598*10294Ssam 
599*10294Ssam 	if (argc < 2) {
600*10294Ssam 		strcat(line, " ");
601*10294Ssam 		printf("(directory-name) ");
602*10294Ssam 		gets(&line[strlen(line)]);
603*10294Ssam 		makeargv();
604*10294Ssam 		argc = margc;
605*10294Ssam 		argv = margv;
606*10294Ssam 	}
607*10294Ssam 	if (argc < 2) {
608*10294Ssam 		printf("%s directory-name\n", argv[0]);
609*10294Ssam 		return;
610*10294Ssam 	}
611*10294Ssam 	(void) command("XRMD %s", argv[1]);
612*10294Ssam }
613*10294Ssam 
614*10294Ssam /*
615*10294Ssam  * Send a line, verbatim, to the remote machine.
616*10294Ssam  */
617*10294Ssam quote(argc, argv)
618*10294Ssam 	char *argv[];
619*10294Ssam {
620*10294Ssam 	int i;
621*10294Ssam 	char buf[BUFSIZ];
622*10294Ssam 
623*10294Ssam 	if (argc < 2) {
624*10294Ssam 		strcat(line, " ");
625*10294Ssam 		printf("(command line to send) ");
626*10294Ssam 		gets(&line[strlen(line)]);
627*10294Ssam 		makeargv();
628*10294Ssam 		argc = margc;
629*10294Ssam 		argv = margv;
630*10294Ssam 	}
631*10294Ssam 	if (argc < 2) {
632*10294Ssam 		printf("usage: %s line-to-send\n", argv[0]);
633*10294Ssam 		return;
634*10294Ssam 	}
635*10294Ssam 	strcpy(buf, argv[1]);
636*10294Ssam 	for (i = 2; i < argc; i++) {
637*10294Ssam 		strcat(buf, " ");
638*10294Ssam 		strcat(buf, argv[i]);
639*10294Ssam 	}
640*10294Ssam 	(void) command(buf);
641*10294Ssam }
642*10294Ssam 
643*10294Ssam /*
644*10294Ssam  * Ask the other side for help.
645*10294Ssam  */
646*10294Ssam rmthelp(argc, argv)
647*10294Ssam 	char *argv[];
648*10294Ssam {
649*10294Ssam 	int oldverbose = verbose;
650*10294Ssam 
651*10294Ssam 	verbose = 1;
652*10294Ssam 	(void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]);
653*10294Ssam 	verbose = oldverbose;
654*10294Ssam }
655*10294Ssam 
656*10294Ssam /*
657*10294Ssam  * Terminate session and exit.
658*10294Ssam  */
659*10294Ssam /*VARARGS*/
660*10294Ssam quit()
661*10294Ssam {
662*10294Ssam 
663*10294Ssam 	disconnect();
664*10294Ssam 	exit(0);
665*10294Ssam }
666*10294Ssam 
667*10294Ssam /*
668*10294Ssam  * Terminate session, but don't exit.
669*10294Ssam  */
670*10294Ssam disconnect()
671*10294Ssam {
672*10294Ssam 	extern FILE *cout;
673*10294Ssam 	extern int data;
674*10294Ssam 
675*10294Ssam 	if (!connected)
676*10294Ssam 		return;
677*10294Ssam 	(void) command("QUIT");
678*10294Ssam 	(void) fclose(cout);
679*10294Ssam 	cout = NULL;
680*10294Ssam 	connected = 0;
681*10294Ssam 	data = -1;
682*10294Ssam }
683