1 /* G C M D L I N -- gkermit command line parser */
9 New York NY 10025-7799 USA
10 http://www.columbia.edu/kermit/
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
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
;
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) );
60 static char gbuf
[GBUFSIZ
], *gargs
[GARGC
], *gptr
= NULL
;
64 int /* Command-line parser */
72 cmarg
= ""; /* Initialize results */
77 if ((p
= getenv("GKERMIT"))) {
81 strncpy(gbuf
,p
,GBUFSIZ
-1); /* Make a pokeable copy */
82 gbuf
[GBUFSIZ
-1] = NUL
;
86 /* Turn it into an argument vector */
88 for (i
= 0; gbuf
[i
] && i
< GBUFSIZ
&& gargc
< GARGC
; i
++) {
93 gargs
[gargc
++] = &gbuf
[i
];
94 } else if (flag
&& gbuf
[i
] <= SP
) {
100 xv
= xargv
; /* Save original argument vector */
102 xargv
= gargs
; /* Redirect it to the one we made */
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 */
112 "?GKERMIT variable option error: \"%s\"\n",
115 usage(); /* Give usage message */
120 xargv
= xv
; /* Restore original argument vector */
123 #endif /* NOGETENV */
125 while (--xargc
> 0) { /* Go through command line words */
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 */
137 return(action
); /* Then do any requested protocol */
140 /* D O A R G -- Do a command-line argument. */
147 #endif /* __STDC__ */
149 int z
; char *xp
, **p
;
151 xp
= *xargv
+1; /* Pointer for bundled args */
154 case 'r': /* Receive */
155 if (action
) fatal("conflicting actions");
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 */
172 xargc
++, *xargv
--; /* Adjust argv/argc */
173 if (nfils
< 1) fatal("missing filename for -s");
178 if (action
) fatal("conflicting actions");
179 if (*(xp
+1)) fatal("invalid argument bundling after -g");
181 if ((xargc
== 0) || (**xargv
== '-'))
182 fatal("missing filename for -g");
192 case 'i': /* Binary (image) file transfer */
197 case 'T': /* Text file transfer */
202 case 'p': /* Parity */
203 if (*(xp
+1)) fatal("invalid argument bundling");
205 if ((xargc
< 1) || (**xargv
== '-'))
206 fatal("missing parity");
207 switch(x
= **xargv
) {
211 case 's': parity
= x
; break; /* Space */
212 case 'n': parity
= 0; break; /* None */
213 default: fatal("invalid parity");
217 case 'w': /* Writeover */
218 backup
= 0; /* Don't back up existing files */
221 case 'd': /* Debug */
224 if ((xargc
< 2) || (**p
== '-')) {
225 db
= fopen("debug.log","w");
228 db
= fopen(*xargv
,"w");
231 extern char * versio
, * build
;
232 if (!versio
) versio
= "";
233 if (!build
) build
= "";
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
);
245 case 'a': /* As-name */
246 if (*(xp
+1)) fatal("invalid argument bundling after -a");
248 if ((xargc
== 0) || (**xargv
== '-'))
249 fatal("missing name for -a");
251 if (debug
) fprintf(db
,"as-name: %s\n",cmarg2
);
255 if (*(xp
+1)) fatal("invalid argument bundling after -e");
257 if ((xargc
< 1) || (**xargv
== '-'))
258 fatal("missing length");
259 z
= atoi(*xargv
); /* Convert to number. */
260 if (z
>= 40 && z
<= MAXRP
) {
262 if (z
> 94) rpsiz
= 94; /* Fallback if other Kermit can't */
263 } else { /* do long packets. */
264 fatal("Unsupported packet length");
268 case 'b': /* Timeout */
269 if (*(xp
+1)) fatal("invalid argument bundling after -b");
271 if ((xargc
< 1) || (**xargv
== '-'))
272 fatal("missing value");
273 z
= atoi(*xargv
); /* Convert to number */
279 case 'P': /* Path (file) names literal */
283 case 'q': /* Quiet */
287 case 'K': /* Keep incompletely received files */
291 case 'S': /* Disable streaming */
295 case 'X': /* gkermit is an external protocol */
296 quiet
= 1; /* No messages */
297 nomodes
= 1; /* Don't set tty modes */
300 case 'x': /* Force Xon/Xoff */
305 case '-': /* Don't force Xon/Xoff */
306 if (*(xp
+1) == 'x') {
310 fatal("invalid argument, type 'gkermit -h' for help");
315 default: /* Anything else */
316 fatal("invalid argument, type 'gkermit -h' for help");
318 x
= *++xp
; /* See if options are bundled */
322 fprintf(db
,"cmdlin action = %c\n",action
);
324 fprintf(db
,"cmdlin action = (none)\n");
330 fatal(msg
) char *msg
; { /* Fatal error message */
331 fprintf(stderr
,"\r\nFatal: %s",msg
); /* doexit supplies crlf.. */
332 doexit(1); /* Exit indicating failure */
337 extern char * versio
, * build
, * url
, * email
;
338 if (!versio
) versio
= "";
339 if (!*versio
) versio
= "gkermit UNKNOWN VERSION";
340 if (!build
) build
= "UNKNOWN BUILD";
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");
366 fprintf(stderr
,"More info: %s <%s>",url
,email
);