Sync usage with man page.
[netbsd-mini2440.git] / gnu / dist / gkermit / gcmdline.c
blob0e3e94c8f81482ac581b17d5dd9d09ffbaf8421b
1 /* G C M D L I N -- gkermit command line parser */
3 /*
4 Author:
5 Frank da Cruz
6 The Kermit Project
7 Columbia University
8 612 West 115th Street
9 New York NY 10025-7799 USA
10 http://www.columbia.edu/kermit/
11 kermit@columbia.edu
13 Copyright (C) 1999,
14 The Trustees of Columbia University in the City of New York.
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 2 of the License, or
19 (at your option) any later version.
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include "gkermit.h"
36 /* Externals */
38 extern int nfils, parity, text, backup, rpsiz, urpsiz, timint;
39 extern int literal, quiet, keep, streamok, nomodes, manual, xonxoff, noxonxoff;
40 extern char ttname[], *cmerrp, *cmarg, *cmarg2;
41 extern FILE * db;
43 /* Variables exported from this module */
45 extern char **cmlist; /* Pointer to file list in argv */
46 extern char **xargv; /* Global copies of argv */
47 extern int xargc; /* and argc */
49 /* Variables and symbols local to this module */
51 static int action = 0; /* Action selected on command line */
53 _MYPROTOTYPE( static int doarg, (char) );
54 _MYPROTOTYPE( VOID fatal, (char *) );
55 _MYPROTOTYPE( VOID usage, (void) );
57 #ifndef NOGETENV
58 #define GARGC 32
59 #define GBUFSIZ 256
60 static char gbuf[GBUFSIZ], *gargs[GARGC], *gptr = NULL;
61 static int gargc;
62 #endif /* NOGETENV */
64 int /* Command-line parser */
65 cmdlin() {
66 char c;
67 int x;
68 #ifndef NOGETENV
69 char * p = NULL;
70 #endif /* NOGETENV */
72 cmarg = ""; /* Initialize results */
73 cmlist = NULL;
74 action = 0;
76 #ifndef NOGETENV
77 if ((p = getenv("GKERMIT"))) {
78 int i, xc, flag = 0;
79 char **xv = NULL;
81 strncpy(gbuf,p,GBUFSIZ-1); /* Make a pokeable copy */
82 gbuf[GBUFSIZ-1] = NUL;
83 gptr = p;
84 p = gbuf;
86 /* Turn it into an argument vector */
88 for (i = 0; gbuf[i] && i < GBUFSIZ && gargc < GARGC; i++) {
89 if (!flag) {
90 if (gbuf[i] <= SP)
91 continue;
92 flag = 1;
93 gargs[gargc++] = &gbuf[i];
94 } else if (flag && gbuf[i] <= SP) {
95 gbuf[i] = NUL;
96 flag = 0;
97 continue;
100 xv = xargv; /* Save original argument vector */
101 xc = xargc;
102 xargv = gargs; /* Redirect it to the one we made */
103 xargc = gargc;
105 while (xargc-- > 0) { /* Go through the words */
106 if (**xargv == '-') { /* Got an option (begins with dash) */
107 c = *(*xargv+1); /* Get the option letter */
108 x = doarg(c); /* Go handle the option */
109 if (x < 0) doexit(1);
110 } else { /* No dash where expected */
111 fprintf(stderr,
112 "?GKERMIT variable option error: \"%s\"\n",
113 *xargv
115 usage(); /* Give usage message */
116 doexit(0);
118 xargv++;
120 xargv = xv; /* Restore original argument vector */
121 xargc = xc;
123 #endif /* NOGETENV */
125 while (--xargc > 0) { /* Go through command line words */
126 xargv++;
127 if (**xargv == '-') { /* Got an option (begins with dash) */
128 c = *(*xargv+1); /* Get the option letter */
129 x = doarg(c); /* Go handle the option */
130 if (x < 0) doexit(1);
131 } else { /* No dash where expected */
132 fprintf(stderr,"?Command-line option error: \"%s\"\n", *xargv);
133 usage(); /* Give usage message */
134 doexit(1);
137 return(action); /* Then do any requested protocol */
140 /* D O A R G -- Do a command-line argument. */
142 static int
143 #ifdef __STDC__
144 doarg(char x)
145 #else
146 doarg(x) char x;
147 #endif /* __STDC__ */
149 int z; char *xp, **p;
151 xp = *xargv+1; /* Pointer for bundled args */
152 while (x) {
153 switch (x) {
154 case 'r': /* Receive */
155 if (action) fatal("conflicting actions");
156 action = 'v';
157 break;
159 case 's': /* Send */
160 if (action) fatal("conflicting actions");
161 if (*(xp+1)) fatal("invalid argument bundling after -s");
162 nfils = 0; /* Initialize file counter, flag */
163 cmlist = xargv+1; /* Remember this pointer */
164 if (zchki(*cmlist) < 0)
165 fatal("file not found or not accessible");
166 while (--xargc > 0) { /* Traverse the list */
167 *xargv++;
168 if (**xargv == '-')
169 break;
170 nfils++;
172 xargc++, *xargv--; /* Adjust argv/argc */
173 if (nfils < 1) fatal("missing filename for -s");
174 action = 's';
175 break;
177 case 'g': /* get */
178 if (action) fatal("conflicting actions");
179 if (*(xp+1)) fatal("invalid argument bundling after -g");
180 *xargv++, xargc--;
181 if ((xargc == 0) || (**xargv == '-'))
182 fatal("missing filename for -g");
183 cmarg = *xargv;
184 action = 'r';
185 break;
187 case 'h': /* Help */
188 case '?':
189 usage();
190 doexit(0);
192 case 'i': /* Binary (image) file transfer */
193 manual = 1;
194 text = 0;
195 break;
197 case 'T': /* Text file transfer */
198 manual = 1;
199 text = 1;
200 break;
202 case 'p': /* Parity */
203 if (*(xp+1)) fatal("invalid argument bundling");
204 *xargv++, xargc--;
205 if ((xargc < 1) || (**xargv == '-'))
206 fatal("missing parity");
207 switch(x = **xargv) {
208 case 'e': /* Even */
209 case 'o': /* Odd */
210 case 'm': /* Mark */
211 case 's': parity = x; break; /* Space */
212 case 'n': parity = 0; break; /* None */
213 default: fatal("invalid parity");
215 break;
217 case 'w': /* Writeover */
218 backup = 0; /* Don't back up existing files */
219 break;
221 case 'd': /* Debug */
222 p = xargv;
223 *p++;
224 if ((xargc < 2) || (**p == '-')) {
225 db = fopen("debug.log","w");
226 } else {
227 *xargv++, xargc--;
228 db = fopen(*xargv,"w");
230 if (db) {
231 extern char * versio, * build;
232 if (!versio) versio = "";
233 if (!build) build = "";
234 debug = 1;
235 setbuf(db,NULL);
236 fprintf(db,"%s: %s\n",
237 (*versio ? versio : "GKERMIT VERSION UNKNOWN"),
238 (*build ? build : "BUILD UNKNOWN")
240 fprintf(db,"MAXPATHLEN = %d\n",MAXPATHLEN);
241 if (gptr) fprintf(db,"GKERMIT=\"%s\"\n",gptr);
243 break;
245 case 'a': /* As-name */
246 if (*(xp+1)) fatal("invalid argument bundling after -a");
247 *xargv++, xargc--;
248 if ((xargc == 0) || (**xargv == '-'))
249 fatal("missing name for -a");
250 cmarg2 = *xargv;
251 if (debug) fprintf(db,"as-name: %s\n",cmarg2);
252 break;
254 case 'e':
255 if (*(xp+1)) fatal("invalid argument bundling after -e");
256 xargv++, xargc--;
257 if ((xargc < 1) || (**xargv == '-'))
258 fatal("missing length");
259 z = atoi(*xargv); /* Convert to number. */
260 if (z >= 40 && z <= MAXRP) {
261 rpsiz = urpsiz = z;
262 if (z > 94) rpsiz = 94; /* Fallback if other Kermit can't */
263 } else { /* do long packets. */
264 fatal("Unsupported packet length");
266 break;
268 case 'b': /* Timeout */
269 if (*(xp+1)) fatal("invalid argument bundling after -b");
270 xargv++, xargc--;
271 if ((xargc < 1) || (**xargv == '-'))
272 fatal("missing value");
273 z = atoi(*xargv); /* Convert to number */
274 if (z < 0) z = 0;
275 if (z > 90) z = 90;
276 timint = z;
277 break;
279 case 'P': /* Path (file) names literal */
280 literal = 1;
281 break;
283 case 'q': /* Quiet */
284 quiet = 1;
285 break;
287 case 'K': /* Keep incompletely received files */
288 keep = 1;
289 break;
291 case 'S': /* Disable streaming */
292 streamok = -1;
293 break;
295 case 'X': /* gkermit is an external protocol */
296 quiet = 1; /* No messages */
297 nomodes = 1; /* Don't set tty modes */
298 break;
300 case 'x': /* Force Xon/Xoff */
301 xonxoff = 1;
302 noxonxoff = 0;
303 break;
305 case '-': /* Don't force Xon/Xoff */
306 if (*(xp+1) == 'x') {
307 xonxoff = 0;
308 noxonxoff = 1;
309 } else {
310 fatal("invalid argument, type 'gkermit -h' for help");
312 xp++;
313 break;
315 default: /* Anything else */
316 fatal("invalid argument, type 'gkermit -h' for help");
318 x = *++xp; /* See if options are bundled */
320 if (debug) {
321 if (action)
322 fprintf(db,"cmdlin action = %c\n",action);
323 else
324 fprintf(db,"cmdlin action = (none)\n");
326 return(action);
329 VOID
330 fatal(msg) char *msg; { /* Fatal error message */
331 fprintf(stderr,"\r\nFatal: %s",msg); /* doexit supplies crlf.. */
332 doexit(1); /* Exit indicating failure */
335 VOID
336 usage() {
337 extern char * versio, * build, * url, * email;
338 if (!versio) versio = "";
339 if (!*versio) versio = "gkermit UNKNOWN VERSION";
340 if (!build) build = "UNKNOWN BUILD";
341 if (!url) url = "";
342 if (!email) email = "";
343 fprintf(stderr,"%s: %s.\n",versio,build);
344 fprintf(stderr,"Usage: gkermit [ options ]\n");
345 fprintf(stderr,"Options:\n");
346 fprintf(stderr," -r Receive files\n");
347 fprintf(stderr," -s fn Send files\n");
348 fprintf(stderr," -g fn Get files from server\n");
349 fprintf(stderr," -a fn As-name for single file\n");
350 fprintf(stderr," -i Image (binary) mode transfer\n");
351 fprintf(stderr," -T Text mode transfer\n");
352 fprintf(stderr," -P Path/filename conversion disabled\n");
353 fprintf(stderr," -w Write over existing files with same name\n");
354 fprintf(stderr," -K Keep incompletely received files\n");
355 fprintf(stderr," -p x Parity: x = o[dd],e[ven],m[ark],s[pace],n[one]\n")
357 fprintf(stderr," -e n Receive packet-length (40-%d)\n",MAXRP);
358 fprintf(stderr," -b n Timeout (sec, 0 = none)\n");
359 fprintf(stderr," -x Force Xon/Xoff (--x = Don't force Xon/Xoff)\n");
360 fprintf(stderr," -S Disable streaming\n");
361 fprintf(stderr," -X External protocol\n");
362 fprintf(stderr," -q Quiet (suppress messages)\n");
363 fprintf(stderr," -d [fn] Debug to ./debug.log [or specified file]\n");
364 fprintf(stderr," -h Help (this message)\n");
365 if (*url || *email)
366 fprintf(stderr,"More info: %s <%s>",url,email);