makefile patch
[ckermit.git] / ckcmai.c
1 #define EDITDATE  "15 Jun 2011"         /* Last edit date dd mmm yyyy */
2 #define EDITNDATE "20110615"            /* Keep them in sync */
3 /* Wed Jun 15 07:12:45 2011 */
4
5 /* ckcmai.c - Main program for C-Kermit plus some miscellaneous functions */
6
7 /*
8   ckcsym.h is used for for defining symbols that normally would be defined
9   using -D or -d on the cc command line, for use with compilers that don't
10   support this feature.  Must come before any tests for preprocessor symbols.
11 */
12 #include "ckcsym.h"
13 /*
14   Consolidated program C-Kermit version information for all platforms
15   (but for UNIX also see ckuver.h).  See makever() below for how they are used.
16 */
17 #ifdef COMMENT                    /* Uncomment this for real K95 version */
18 #ifndef OS2                             /* OS2 actually means Kermit 95. */
19 #ifndef BETATEST                        /* It's because Kermit 95 started */
20 #define BETATEST                        /* out as C-Kermit for OS/2. */
21 #endif /* BETATEST */
22 #endif /* OS2 */
23 #endif /* COMMENT */
24
25 #ifdef BETATEST
26 #ifdef OS2
27 #ifdef __DATE__
28 #define BETADATE
29 #endif /* __DATE__ */
30 #endif /* OS2 */
31 #endif /* BETATEST */
32
33 char * ck_cryear = "2011";              /* C-Kermit copyright year */
34
35 #ifndef MAC                             /* MAC = Kermit for MAC OS 6, 7, ... */
36 /*
37   Note: initialize ck_s_test to "" if this is not a test version.
38   Use (*ck_s_test != '\0') to decide whether to print test-related messages.
39 */
40
41 #ifndef BETATEST
42 #ifndef OS2                             /* UNIX, VMS, etc... (i.e. C-Kermit) */
43 char *ck_s_test = "Beta";               /* "Dev","Alpha","Beta","RC", or "" */
44 char *ck_s_tver = "01";                 /* Test version number or "" */
45 #else  /* OS2 */
46 char *ck_s_test = "";                   /* (i.e. K95) */
47 char *ck_s_tver = "";
48 #endif /* OS2 */
49 #else
50 char *ck_s_test = "";                   /* Development */
51 char *ck_s_tver = "";
52 #endif /* BETATEST */
53 #else /* MAC */
54 char *ck_s_test = "Pre-Alpha";          /* Mac Kermit is always a test... */
55 char *ck_s_tver = "";                   /* (pre Mac OS X 10, that is!) */
56 #endif /* MAC */
57
58 #ifdef BETADATE                         /* Date of this version or edit */
59 char *ck_s_date = __DATE__;             /* Compilation date */
60 #else
61 char *ck_s_date = EDITDATE;             /* See top */
62
63 #endif /* BETADATE */
64 char *buildid = EDITNDATE;              /* See top */
65
66 #ifdef UNIX
67 static char sccsid[] = "@(#)C-Kermit 9.0.299";
68 #endif /* UNIX */
69
70 char *ck_s_ver = "9.0.299";             /* C-Kermit version string */
71 long  ck_l_ver =  900299L;              /* C-Kermit version number */
72
73 #ifdef OS2
74 char *ck_s_xver = "3.0.0";              /* Product-specific version string */
75 long  ck_l_xver = 3000L;                /* Product-specific version number */
76 #else
77 #ifdef MAC
78 char *ck_s_xver = "0.995";              /* Product-specific version string */
79 long  ck_l_xver = 995L;                 /* Product-specific version number */
80 #else
81 char *ck_s_xver = "";                   /* Don't touch these... */
82 long  ck_l_xver = 0L;                   /* they are computed at runtime */
83 #endif /* MAC */
84 #endif /* OS2 */
85
86 #ifdef OS2
87 #ifdef IKSDONLY
88 #ifdef NT
89 char *ck_s_name = "IKS-NT";
90 #else /* NT */
91 char *ck_s_name = "IKS-OS/2";
92 #endif /* NT */
93 #else /* IKSDONLY */
94 char *ck_s_name = "Kermit 95";          /* Program name */
95 #endif /* IKSDONLY */
96 #else
97 #ifdef MAC
98 char *ck_s_name = "Mac Kermit";
99 #else
100 char *ck_s_name = "C-Kermit";
101 #endif /* MAC */
102 #endif /* OS2 */
103
104 char *ck_s_who = "";                    /* Where customized, "" = not. */
105 char *ck_patch = "";                    /* Patch info, if any. */
106
107 #define CKVERLEN 128
108 char versiox[CKVERLEN];                 /* Version string buffer  */
109 char *versio = versiox;                 /* These are filled in at */
110 long vernum, xvernum;                   /* runtime from above.    */
111
112 #define CKCMAI
113
114 #include "ckcasc.h"                     /* ASCII character symbols */
115 #include "ckcdeb.h"                     /* Debug & other symbols */
116
117 char * myname = NULL;                   /* The name I am called by */
118 #ifndef OS2
119 char * exedir = NULL;                   /* Directory I was executed from */
120 #endif /* OS2 */
121 char * myhome = NULL;                   /* Home directory override */
122
123 /*  C K C M A I  --  C-Kermit Main program  */
124
125 /*
126   Author: Frank da Cruz (fdc@columbia.edu),
127   Columbia University in the city of New York,
128   Computer Center / Center for Computing Activities / Information Technology.
129   I am no longer at Columbia U as of 1 July 2011, but the email address
130   should still work.  The Kermit website http://kermit.columbia.edu should
131   still be available and under my control, as well as the Kermit FTP site,
132   ftp://kermit.columbia.edu/kermit/.
133
134 COPYRIGHT NOTICE:
135 */
136
137 char *copyright[] = {
138
139 #ifdef pdp11
140 "Copyright (C) 1985, %s, Trustees of Columbia University, NYC.",
141 "All rights reserved.",
142 " ",
143 #else
144 "Copyright (C) 1985, %s,",
145 "  The Trustees of Columbia University in the City of New York.",
146 "  All rights reserved.",
147 " ",
148 "Redistribution and use in source and binary forms, with or without",
149 "modification, are permitted provided that the following conditions",
150 "are met:",
151 " ",
152 " + Redistributions of source code must retain the above copyright",
153 "   notice, this list of conditions and the following disclaimer.",
154 " ",
155 " + Redistributions in binary form must reproduce the above copyright",
156 "   notice, this list of conditions and the following disclaimer in",
157 "   the documentation and/or other materials provided with the",
158 "   distribution.",
159 " ",
160 " + Neither the name of the <ORGANIZATION> nor the names of its",
161 "   contributors may be used to endorse or promote products derived",
162 "   from this software without specific prior written permission.",
163 " ",
164 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS",
165 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT",
166 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR",
167 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT",
168 "HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,",
169 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT",
170 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,",
171 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY",
172 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT",
173 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE",
174 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
175 #endif /* pdp11 */
176
177 #ifdef OS2
178 "Portions Copyright (C) 2002-2005, Secure Endpoints Inc, New York NY USA.",
179 "Portions Copyright (C) 1995, Oy Online Solutions Ltd., Jyvaskyla, Finland.",
180 #endif /* OS2 */
181
182 #ifdef CK_AUTHENTICATION
183 "Portions Copyright (C) 1990, Massachusetts Institute of Technology.",
184 #ifdef CK_ENCRYPTION
185 "Portions Copyright (C) 1991, 1993 Regents of the University of California.",
186 "Portions Copyright (C) 1991, 1992, 1993, 1994, 1995 by AT&T.",
187 "Portions Copyright (C) 1995, 1997, Eric Young <eay@cryptosoft.com>.",
188 #endif /* CK_ENCRYPTION */
189 #ifdef CK_SRP
190 "Portions Copyright (C) 1997, Stanford University.",
191 #endif /* CK_SRP */
192 #endif /* CK_AUTHENTICATION */
193
194 #ifndef pdp11
195 " ",
196 "For further information, visit the Kermit Project website:",
197 "http://www.columbia.edu/kermit/ .",
198 #endif /* pdp11 */
199 ""};
200
201 /* Windows IKSD copyright used to be separate */
202 char *wiksdcpr = (char *) copyright;
203
204
205 /*
206 DOCUMENTATION:
207
208  "Using C-Kermit" by Frank da Cruz and Christine M. Gianone,
209   Digital Press / Butterworth-Heinemann, Woburn MA, USA.
210   Second edition (1997), ISBN 1-55558-164-1.
211   Order from Digital Press:    +1 (800) 366-2665
212   Or from Columbia University: +1 (212) 854-3703
213
214 For Kermit 95, also:
215
216   "Kermit 95" by Christine M. Gianone and Frank da Cruz,
217   Manning Publications, Greenwich CT, USA (1998) - Online.
218
219 ACKNOWLEDGMENTS:
220
221   The Kermit file transfer protocol was developed at the Columbia University
222   Center for Computing Activities (CUCCA), which was since renamed to Columbia
223   University Academic Information Systems (AcIS) and after that Columbia
224   University Information Technology (CUIT).  Kermit is named after Kermit the
225   Frog, star of the television series THE MUPPET SHOW; the name is used by
226   permission of Henson Associates, Inc.
227
228   Thanks to at least the following people for their contributions to this
229   program over the years, and apologies to anyone who was inadvertantly
230   omitted:
231
232    Chris Adie, Edinburgh U, Scotland (OS/2)
233    Robert Adsett, University of Waterloo, Canada
234    Larry Afrin, Clemson U
235    Russ Allbery, Stanford U
236    Jeffrey Altman, Columbia University
237    Greg Andrews, Telebit Corp
238    Barry Archer, U of Missouri
239    Robert Andersson, International Systems A/S, Oslo, Norway
240    Chris Armstrong, Brookhaven National Lab (OS/2)
241    William Bader, Software Consulting Services, Nazareth, PA
242    Fuat Baran, Columbia U
243    Stan Barber, Rice U
244    Jim Barbour, U of Colorado
245    Donn Baumgartner, Dell
246    Ian Beckwith, Debian Project
247    Nelson Beebe, U of Utah
248    Gerry Belanger, Cognitronics
249    Karl Berry, UMB
250    Mark Berryman, SAIC
251    Dean W Bettinger, SUNY
252    Gary Bilkus
253    Peter Binderup, Denmark
254    David Bolen, Advanced Networks and Services, Inc.
255    Joop Bonen
256    Marc Boucher, U of Montreal
257    Charles Brooks, EDN
258    Bob Brown
259    Mike Brown, Purdue U
260    Rob Brown
261    Jack Bryans, California State U at Long Beach
262    Mark Buda, DEC (VMS)
263    Fernando Cabral, Padrao iX, Brasilia
264    Bjorn Carlsson, Stockholm University Computer Centre QZ, Sweden
265    Bill Catchings, (formerly of) Columbia U
266    Bob Cattani, Columbia U CS Dept
267    Davide Cervone, Rochester U
268    Seth Chaiklin, Denmark
269    John Chandler, Harvard U / Smithsonian Astronomical Observatory
270    Bernard Chen, UCLA
271    Andrew A Chernov, RELCOM Team, Moscow
272    John L Chmielewski, AT&T, Lisle, IL
273    Howard Chu, U of Michigan
274    Bill Coalson, McDonnell Douglas
275    Bertie Coopersmith, London
276    Christian Corti
277    Chet Creider, U of Western Ontario
278    Alan Crosswell, Columbia U
279    Jeff Damens, (formerly of) Columbia U
280    Mark Davies, Bath U, UK
281    Sin-itirou Dezawa, Fujifilm, Japan
282    Joe R. Doupnik, Utah State U
283    Frank Dreano, Honeywell
284    John Dunlap, U of Washington
285    Alex Dupuy, SMART.COM
286    David Dyck, John Fluke Mfg Co.
287    Stefaan A. Eeckels, Eurokom, Luxembourg
288    Nick Efthymiou
289    Paul Eggert, Twin Sun, Inc., El Segundo, CA
290    Bernie Eiben, DEC
291    Peter Eichhorn, Assyst International
292    Kristoffer Eriksson, Peridot Konsult AB, Oerebro, Sweden
293    John R. Evans, IRS, Kansas City
294    Glenn Everhart, RCA Labs
295    Charlie Finan, Cray Research
296    Herm Fischer, Encino, CA (extensive contributions to version 4.0)
297    Carl Fongheiser, CWRU
298    Mike Freeman, Bonneville Power Authority
299    Carl Friedberg
300    Marcello Frutig, Catholic University, Sao Paulo, Brazil (X.25 support)
301    Hirofumi Fujii, Japan Nat'l Lab for High Energy Physics, Tokyo (Kanji)
302    Chuck Fuller, Westinghouse Corporate Computer Services
303    Andy Fyfe, Caltech
304    Christine M. Gianone, Columbia U
305    John Gilmore, UC Berkeley
306    Madhusudan Giyyarpuram, HP
307    Rainer Glaschick, Siemens AG, Paderborn
308    William H. Glass
309    German Goldszmidt, IBM
310    Chuck Goodhart, NASA
311    Alistair Gorman, New Zealand
312    Richard Gration, ADFA, Australia
313    Chris Green, Essex U, UK
314    Alan Grieg, Dundee Tech, Scotland
315    Yekta Gursel, MIT
316    Jim Guyton, Rand Corp
317    Michael Haertel
318    Bruno Haible
319    Bob Hain, UMN
320    Marion Hakanson, ORST
321    Richard Hamilton
322    John Hamilston, Iowa State U
323    Simon Hania, Netherlands
324    Stan Hanks, Rice U.
325    Ken Harrenstein, SRI
326    Eugenia Harris, Data General (AOS/VS)
327    David Harrison, Kingston Warren Corp
328    Lucas Hart, Oregon State University
329    James Harvey, Indiana/Purdue U (VMS)
330    Rob Healey
331    Chuck Hedrick, Rutgers U
332    Ron Heiby, Technical Systems Division, Motorola Computer Group
333    Steve Hemminger, Tektronix
334    Christian Hemsing, RWTH Aachen, Germany (OS-9)
335    Randolph Herber, US DOE,
336    Andrew Herbert, Monash Univ, Australia
337    Marcus Herbert, Germany
338    Mike Hickey, ITI
339    Dan Hildebrand, QNX Software Systems Inc, Kanata, ON (QNX)
340    R E Hill
341    Stephan Hoffman-Emden
342    Sven Holmstrom, ABB Utilities AB, Sweden
343    Bill Homer, Cray Research
344    Ray Hunter, The Wollongong Group
345    Randy Huntziger, National Library of Medicine
346    Larry Jacobs, Transarc
347    Steve Jenkins, Lancaster University, UK
348    Dave Johnson, Gradient Technologies
349    Mark B Johnson, Apple Computer
350    Jyke Jokinen, Tampere University of Technology, Finland (QNX)
351    Eric F Jones, AT&T
352    Luke Jones, AT&T
353    Peter Jones, U of Quebec Montreal
354    Phil Julian, SAS Institute
355    Peter Kabal, U of Quebec
356    Mic Kaczmarczik, U of Texas at Austin
357    Sergey Kartashoff, Inst. of Precise Mechanics & Computer Equipment, Moscow
358    Howie Kaye, Columbia U
359    Rob Kedoin, Linotype Co, Hauppauge, NY (OS/2)
360    Phil Keegstra
361    Mark Kennedy, IBM
362    Terry Kennedy, St Peter's College, Jersey City, NJ (VMS and more)
363    "Carlo Kid", Technical University of Delft, Netherlands
364    Tim Kientzle
365    Paul Kimoto, Cornell U
366    Douglas Kingston, morgan.com
367    Lawrence Kirby, Wiltshire, UK
368    Tom Kloos, Sequent Computer Systems
369    Guenter Knauf
370    Jim Knutson, U of Texas at Austin
371    John T. Kohl (BSDI)
372    Scott Kramer, SRI International, Menlo Park, CA
373    John Kraynack, US Postal Service
374    David Kricker, Encore Computer
375    Thomas Krueger, UWM
376    Bo Kullmar, ABC Klubben, Stockholm, and Central Bank of Sweden, Kista
377    R. Brad Kummer, AT&T Bell Labs, Atlanta, GA
378    John Kunze, UC Berkeley
379    David Lane, BSSI / BellSouth (Stratus VOS, X.25)
380    Bob Larson, USC (OS-9)
381    Bert Laverman, Groningen U, Netherlands
382    Steve Layton
383    David Lawyer, UC Irvine
384    Jason Lehr
385    David LeVine, National Semiconductor Corporation
386    Daniel S. Lewart, UIUC
387    S.O. Lidie, Lehigh U
388    Tor Lillqvist, Helsinki U, Finland
389    David-Michael Lincke, U of St Gallen, Switzerland
390    Robert Lipe (for SCO makefile entries & advice)
391    Dean Long
392    Mike Long, Analog Devices, Norwood MA
393    Kevin Lowey, U of Saskatchewan (OS/2)
394    Andy Lowry, Columbia U
395    James Lummel, Caprica Telecomputing Resources (QNX)
396    Lewis McCarthy
397    David MacKenzie, Environmental Defense Fund, U of Maryland
398    John Mackin, University of Sidney, Australia
399    Martin Maclaren, Bath U, UK
400    Chris Maio, Columbia U CS Dept
401    Montserrat Mane, HP, Grenoble, France
402    Fulvio Marino, Olivetti, Ivrea, Italy
403    Arthur Marsh, dircsa.org.au
404    Peter Mauzey, Lucent Technologies
405    Tye McQueen, Utah State U
406    Ted Medin
407    Hellmuth Michaelis, Hanseatischer Computerservice GmbH, Hamburg, Germany
408    Leslie Mikesell, American Farm Bureau
409    Todd Miller, Courtesan Consulting
410    Gary Mills
411    Martin Minow, DEC (VMS)
412    Pawan Misra, Bellcore
413    Ken Mizialko, IBM, Manassas, VA
414    Wolfgang Moeller, DECUS Germany
415    Ray Moody, Purdue U
416    Bruce J Moore, Allen-Bradley Co, Highland Heights, OH (Atari ST)
417    Steve Morley, Convex
418    Peter Mossel, Columbia U
419    Tony Movshon, NYU
420    Lou Muccioli, Swanson Analysis Systems
421    Dan Murphy
422    Neal P. Murphy, Harsof Systems, Wonder Lake IL
423    Gary Mussar
424    John Nall, FSU
425    Jack Nelson, U of Pittsburgh
426    Jim Noble, Planning Research Corporation (Macintosh)
427    Ian O'Brien, Bath U, UK
428    Melissa O'Neill, SFU
429    John Owens
430    Thomas Pinkl, Health Business Systems Inc.
431    Michael Pins, Iowa Computer Aided Engineering Network
432    Andre' Pirard, University of Liege, Belgium
433    Paul Placeway, Ohio State U
434    Piet W. Plomp, ICCE, Groningen University, Netherlands
435    Ken Poulton, HP Labs
436    Manfred Prange, Oakland U
437    Christopher Pratt, APV Baker, UK
438    Frank Prindle, NADC
439    Tony Querubin, U of Hawaii
440    Jean-Pierre Radley
441    Anton Rang
442    Mike Rechtman
443    Scott Ribe
444    Alan Robiette, Oxford University, UK
445    Michel Robitaille, U of Montreal (Mac)
446    Huw Rogers, Schweizerische Kreditanstalt, Zuerich
447    Nigel Roles, Cambridge, England
448    Kai Uwe Rommel, Technische Universitaet Muenchen (OS/2)
449    Larry Rosenman (Amiga)
450    Jay Rouman, U of Michigan
451    Jack Rouse, SAS Institute (Data General and/or Apollo)
452    Stew Rubenstein, Harvard U (VMS)
453    Gerhard Rueckle, FH Darmstadt, Fb. E/Automatisierungstechnik
454    John Santos, EG&H
455    Bill Schilit, Columbia U
456    Ulli Schlueter, RWTH Aachen, Germany (OS-9, etc)
457    Michael Schmidt, U of Paderborn, Germany
458    Eric Schnoebelen, Convex
459    Benn Schreiber, DEC
460    Dan Schullman, DEC (modems, DIAL command, etc)
461    John Schultz, 3M
462    Steven Schultz, Contel (PDP-11)
463    Steven Schweda
464    APPP Scorer, Leeds Polytechnic, UK
465    Gordon Scott, Micro Focus, Newbury UK
466    Gisbert W. Selke, WIdO, Bonn, Germany
467    Kijal Shah
468    David Singer, IBM Almaden Research Labs
469    David Sizeland, U of London Medical School
470    Fridrik Skulason, Iceland
471    Rick Sladkey (Linux)
472    Dave Slate
473    Bradley Smith, UCLA
474    Fred Smith, Merk / Computrition
475    Richard S Smith, Cal State
476    Ryan Stanisfer, UNT
477    Bertil Stenstroem, Stockholm University Computer Centre (QZ), Sweden
478    James Sturdevant, CAP GEMENI AMERICA, Minneapolis
479    Peter Svanberg, Royal Techn. HS, Sweden
480    James R. Swenson, Accu-Weather, Inc.
481    Ted T'so, MIT (Linux)
482    Andy Tanenbaum, Vrije U, Amsterdam, Netherlands
483    Seth Theriault, Columbia U
484    Glen Thobe
485    Markku Toijala, Helsinki U of Technology
486    Teemu Torma, Helsinki U of Technology
487    Linus Torvalds, Helsinki
488    Rick Troxel, NIH
489    Warren Tucker, Tridom Corp, Mountain Park, GA
490    Dave Tweten, AMES-NAS
491    G Uddeborg, Sweden
492    Walter Underwood, Ford Aerospace
493    Pieter Van Der Linden, Centre Mondial, Paris
494    Ge van Geldorp, Netherlands
495    Fred van Kempen, MINIX User Group, Voorhout, Netherlands
496    Wayne Van Pelt, GE/CRD
497    Mark Vasoll, Oklahoma State U (V7 UNIX)
498    Konstantin Vinogradov, ICSTI, Moscow
499    Paul Vixie, DEC
500    Bernie Volz, Process Software
501    Eduard Vopicka, Prague University of Economics, Czech Republic
502    Martin Vorlaender
503    Dimitri Vulis, CUNY
504    Roger Wallace, Raytheon
505    Stephen Walton, Calif State U, Northridge (Amiga)
506    Jamie Watson, Adasoft, Switzerland (AIX)
507    Rick Watson, U of Texas (Macintosh)
508    Eric Weaver, Columbia U
509    Scott Weikart (Association for Progressive Communications)
510    Robert Weiner, Programming Plus, New York City
511    Lauren Weinstein, Vortex Technlogy
512    David Wexelblat, AT&T
513    Clark Wierda, Illuminati Online
514    Joachim Wiesel, U of Karlsruhe
515    Lon Willett, U of Utah
516    Michael Williams, UCLA
517    Nate Williams, U of Montana
518    David Wilson
519    Joellen Windsor, U of Arizona
520    Patrick Wolfe, Kuck & Associates, Inc.
521    Gregg Wonderly, Oklahoma State U (V7 UNIX)
522    Farrell Woods, Concurrent (formerly Masscomp)
523    Dave Woolley, CAP Communication Systems, London
524    Jack Woolley, SCT Corp
525    Frank Wortner
526    Ken Yap, formerly of U of Rochester
527    John Zeeff, Ann Arbor, MI
528 */
529
530 #include "ckcker.h"                     /* Kermit symbols */
531 #include "ckcnet.h"                     /* Network symbols */
532
533 #ifdef CK_SSL
534 #include "ck_ssl.h"
535 #endif /* CK_SSL */
536
537 #ifndef NOSPL
538 #include "ckuusr.h"
539 #endif /* NOSPL */
540
541 #ifdef OS2ONLY
542 #define INCL_VIO                        /* Needed for ckocon.h */
543 #include <os2.h>
544 #undef COMMENT
545 #endif /* OS2ONLY */
546
547 #ifdef NT
548 #include <windows.h>
549 #include <tapi.h>
550 #include "ckntap.h"
551 #endif /* NT */
552
553 #ifndef NOSERVER
554 /* Text message definitions.. each should be 256 chars long, or less. */
555 #ifdef MINIX
556 char *srvtxt = "\r\n\
557 Entering server mode.\r\n\0";
558 #else
559 #ifdef OLDMSG
560 /*
561   It seems there was a large installation that was using C-Kermit 5A(165)
562   or thereabouts, which had deployed thousands of MS-DOS Kermit scripts in
563   scattered locations that looked for strings in the old server message,
564   which changed in 5A(183), August 1992.
565 */
566 char *srvtxt = "\r\n\
567 C-Kermit server starting.  Return to your local machine by typing\r\n\
568 its escape sequence for closing the connection, and issue further\r\n\
569 commands from there.  To shut down the C-Kermit server, issue the\r\n\
570 FINISH or BYE command and then reconnect.\n\
571 \r\n\0";
572 #else
573 #ifdef OSK
574 char *srvtxt = "\r\012\
575 Entering server mode.  If your local Kermit software is menu driven, use\r\012\
576 the menus to send commands to the server.  Otherwise, enter the escape\r\012\
577 sequence to return to your local Kermit prompt and issue commands from\r\012\
578 there. Use SEND and GET for file transfer. Use REMOTE HELP for a list of\r\012\
579 other available services.  Use BYE or FINISH to end server mode.\r\012\0";
580 #else /* UNIX, VMS, AOS/VS, and all others */
581 char *srvtxt = "\r\n\
582 Entering server mode.  If your local Kermit software is menu driven, use\r\n\
583 the menus to send commands to the server.  Otherwise, enter the escape\r\n\
584 sequence to return to your local Kermit prompt and issue commands from\r\n\
585 there.  Use SEND and GET for file transfer.  Use REMOTE HELP for a list of\r\n\
586 other available services.  Use BYE or FINISH to end server mode.\r\n\0";
587 #endif /* OSK */
588 #endif /* OLDMSG */
589 #endif /* MINIX */
590 #else  /* server mode disabled */
591 char *srvtxt = "";
592 #endif /* NOSERVER */
593
594 int initflg = 0;                        /* sysinit() has executed... */
595 int howcalled = I_AM_KERMIT;            /* How I was called */
596 int hmtopline = 0;
597 int quitting = 0;                       /* I'm in the act of quitting */
598
599 #ifdef IKSDCONF
600 char * iksdconf = IKSDCONF;             /* IKSD configuration file */
601 int    iksdcf   = 0;                    /* Has IKSD c.f. been processed? */
602 #endif /* IKSDCONF */
603
604 int srvcdmsg = 0;                       /* [Server] CD message */
605 char * cdmsgfile[8] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
606 char * cdmsgstr = NULL;
607 char * ckcdpath = NULL;
608
609 #ifdef NLCHAR                           /* Text-file line terminator */
610 CHAR feol = NLCHAR;
611 #else
612 CHAR feol = 0;
613 #endif /* NLCHAR */
614
615 int fblksiz = DBLKSIZ;          /* File blocksize */
616 int frecl = DLRECL;             /* File record length */
617 int frecfm = XYFF_S;            /* File record format (default = stream) */
618 int forg = XYFO_S;              /* File organization (sequential) */
619 int fcctrl = XYFP_N;            /* File carriage control (ctrl chars) */
620 int filecase = FILECASE;        /* Case matters in filenames */
621 int stathack = 1;               /* Fast directory lookups by default */
622
623 char uidbuf[UIDBUFLEN] = { NUL, NUL };  /* User ID buffer */
624 int cfilef = 0;                         /* Application ("kerbang") file flag */
625 char cmdfil[CKMAXPATH + 1] = { NUL, NUL }; /* Application file name */
626 int haveurl = 0;                        /* URL given on command line */
627
628 #ifndef NOXFER
629 /* Multi-protocol support */
630
631 struct ck_p ptab[NPROTOS] = {           /* Initialize the Kermit part ... */
632   { "Kermit",
633     DRPSIZ,                             /* Receive packet size */
634     DSPSIZ,                             /* Send packet size */
635     0,                                  /* Send-packet-size-set flag */
636     DFWSIZ,                             /* Window size */
637
638 #ifdef NEWDEFAULTS
639     PX_CAU,                             /* Control char unprefixing... */
640 #else
641     PX_ALL,
642 #endif /* NEWDEFAULTS */
643
644 #ifdef VMS                              /* Default filename collision action */
645     XYFX_X,                             /* REPLACE for VAX/VMS */
646 #else
647     XYFX_B,                             /* BACKUP for everybody else */
648 #endif /* VMS */
649
650 #ifdef OS2                              /* Flag for file name conversion */
651     XYFN_L,                             /* Literal for OS2 */
652 #else
653     XYFN_C,                             /* Converted for others */
654 #endif /* OS2 */
655
656     PATH_OFF,                   /* Send pathnames OFF */
657     PATH_AUTO,                  /* Receive pathnames AUTO */
658     NULL,                       /* Host receive initiation string (binary) */
659     NULL,                       /* Host receive initiation string (text)   */
660     NULL,                       /* Host server string */
661     NULL,                       /* External protocol send command (binary) */
662     NULL,                       /* External protocol send command (text)   */
663     NULL,                       /* External protocol receive command (bin) */
664     NULL }                      /* External protocol receive command (txt) */
665 #ifdef CK_XYZ
666 ,
667 {"XMODEM",    128,128,-1,-1,   1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
668 {"XMODEM-CRC",128,128,-1,-1,  -1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
669 {"YMODEM",   -1, -1,-1,-1,    -1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
670 {"YMODEM-g", -1, -1,-1,-1,    -1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
671 {"ZMODEM",   -1, -1,-1,-1,PX_WIL,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
672 {"Other",    -1, -1,-1,-1,    -1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL}
673 #endif /* CK_XYZ */
674 };
675
676 /* Declarations for Send-Init Parameters */
677
678 int spsiz = DSPSIZ,                     /* Current packet size to send */
679     spmax = DSPSIZ,                     /* Biggest packet size we can send */
680     lastspmax = DSPSIZ,                 /* Send-packet size last used */
681     spsizr = DSPSIZ,                    /* Send-packet size requested */
682     spsizf = 0,                         /* Flag to override size negotiation */
683     rpsiz = DRPSIZ,                     /* Biggest we want to receive */
684     urpsiz = DRPSIZ,                    /* User-requested receive pkt size */
685     maxrps = MAXRP,                     /* Maximum incoming long packet size */
686     maxsps = MAXSP,                     /* Maximum outbound l.p. size */
687     maxtry = MAXTRY,                    /* Maximum retries per packet */
688     wslots = 1,                         /* Window size currently in use */
689     wslotr = DFWSIZ,                    /* Window size from SET WINDOW */
690     wslotn = 1,                         /* Window size negotiated in S-pkt */
691     timeouts = 0,                       /* For statistics reporting */
692     spackets = 0,                       /*  ... */
693     rpackets = 0,                       /*  ... */
694     retrans = 0,                        /*  ... */
695     crunched = 0,                       /*  ... */
696     wmax = 0,                           /*  ... */
697     wcur = 0,                           /*  ... */
698     srvidl = 0,                         /* Server idle timeout */
699     srvdis = 1,                         /* Server file xfer display */
700     srvtim = DSRVTIM,                   /* Server command wait timeout */
701     srvping = 1,                        /* Server keepalive */
702 /*
703   timint is the timeout interval I use when waiting for a packet.
704   pkttim is the SET RECEIVE TIMEOUT value, sent to the other Kermit.
705   rtimo is the SET SEND TIMEOUT value.  rtimo is the initial value of
706   timint.  timint is changed by the value in the incoming negotiation
707   packet unless a SET SEND TIMEOUT command was given.
708 */
709     timint = DMYTIM,                    /* Timeout interval I use */
710     pkttim = URTIME,                    /* Timeout I want you to use */
711     rtimo = DMYTIM,                     /* Normal packet wait timeout */
712     timef = 0,                          /* Flag to override what you ask */
713 #ifdef CK_TIMERS
714     rttflg = 1,                         /* Use dynamic round-trip timers */
715 #else
716     rttflg = 0,                         /* Use fixed timer */
717 #endif /* CK_TIMERS */
718     mintime = 1,                        /* Minimum timeout */
719     maxtime = 0,                        /* Maximum timeout */
720
721     npad = MYPADN,                      /* How much padding to send */
722     mypadn = MYPADN,                    /* How much padding to ask for */
723     bctr = DFBCT,                       /* Block check type requested */
724     bctu = 1,                           /* Block check type used */
725     bctl = 1,                           /* Block check length */
726     bctf = 0,                           /* Block check type 3 forced on all */
727     c_save = -1,                        /* Block check saving and restoring */
728     ss_save = -1,                       /* Slow-start saving and restoring */
729     ebq =  MYEBQ,                       /* 8th bit prefix */
730     ebqflg = 0,                         /* 8th-bit quoting flag */
731     rqf = -1,                           /* Flag used in 8bq negotiation */
732     rq = 0,                             /* Received 8bq bid */
733     sq = 'Y',                           /* Sent 8bq bid */
734     rpt = 0,                            /* Repeat count */
735     rptq = MYRPTQ,                      /* Repeat prefix */
736     rptflg = 0,                         /* Repeat processing flag */
737     rptena = 1,                         /* Repeat processing enabled */
738     xfrcan = 1,                         /* Transfer cancellation enabled */
739     xfrint = 1,                         /* Transfer interruption enabled */
740     xfrchr = 3,                         /* Transfer cancel char = Ctrl-C */
741     xfrnum = 3,                         /* Need three of them by default */
742     g_xfrxla = -1;
743     char * xfrmsg = NULL;               /* Message for f.t. display screen */
744 #endif /* NOXFER */
745
746 #ifdef NOCSETS
747 int xfrxla = 0;                         /* Character-set translation */
748 #else
749 int xfrxla = 1;                         /* enabled or disabled */
750 #endif /* NOCSETS */
751
752 int havelfs = 0;                        /* Large file support available */
753
754 #ifndef NOXFER
755 int epktflg = 0;                        /* E-PACKET command active */
756
757 int capas  = 9,                         /* Position of Capabilities */
758     lpcapb = 2,                         /* Long Packet capability */
759     lpcapr = 1,                         /*  requested */
760     lpcapu = 0,                         /*  used */
761     swcapb = 4,                         /* Sliding Window capability */
762     swcapr = 1,                         /*  requested (allowed) */
763     swcapu = 0,                         /*  used */
764     atcapb = 8,                         /* Attribute capability */
765     atcapr = 1,                         /*  requested */
766     atcapu = 0,                         /*  used */
767     rscapb = 16,                        /* RESEND capability */
768     rscapr = 1,                         /*  requested by default */
769     rscapu = 0,                         /*  used */
770     lscapb = 32,                        /* Locking Shift capability */
771     lscapr = 1,                         /*  requested by default */
772     lscapu = 0;                         /*  used */
773
774 /* Flags for whether to use particular attributes */
775
776 int atenci = 1,                         /* Encoding in */
777     atenco = 1,                         /* Encoding out */
778     atdati = 1,                         /* Date in */
779     atdato = 1,                         /* Date out */
780     atdisi = 1,                         /* Disposition in/out */
781     atdiso = 1,
782     atleni = 1,                         /* Length in/out (both kinds) */
783     atleno = 1,
784     atblki = 1,                         /* Blocksize in/out */
785     atblko = 1,
786     attypi = 1,                         /* File type in/out */
787     attypo = 1,
788     atsidi = 1,                         /* System ID in/out */
789     atsido = 1,
790     atsysi = 1,                        /* System-dependent parameters in/out */
791     atsyso = 1;
792
793 int dispos = 0;                         /* Disposition */
794
795 #ifdef CK_PERMS
796 int atlpri = 1,
797     atlpro = 1,
798     atgpri = 1,
799     atgpro = 1;
800 #endif /* CK_PERMS */
801
802 int atfrmi = 1,                         /* Record Format in/out */
803     atfrmo = 1;
804
805 #ifdef STRATUS
806 int atcrei = 1,                         /* Creator ID in/out */
807     atcreo = 1,
808     atacti = 1,                         /* Account in/out */
809     atacto = 1;
810 #endif /* STRATUS */
811
812 int sprmlen = -1;                       /* Send/Receive protocol parameter */
813 int rprmlen = -1;                       /* string length limits */
814 int sendipkts = 1;                      /* Send I packets */
815
816 CHAR padch = MYPADC,                    /* Padding character to send */
817     mypadc = MYPADC,                    /* Padding character to ask for */
818     seol = MYEOL,                       /* End-Of-Line character to send */
819     eol = MYEOL,                        /* End-Of-Line character to look for */
820     ctlq = CTLQ,                        /* Control prefix in incoming data */
821     myctlq = CTLQ,                      /* Outbound control character prefix */
822     myrptq = MYRPTQ;                    /* Repeat prefix I want to use */
823
824 int rptmin = 3;                         /* Repeat-count minimum */
825
826 int usepipes = 0,                       /* Used for xfer to/from pipes */
827     g_usepipes = -1;
828
829 char * filefile = NULL;                 /* File containing list of filenames */
830 /* CD message filename list */
831
832 char whoareu[16] = { NUL, NUL };        /* System ID of other Kermit */
833 int sysindex = -1;                      /* and index to its system ID struct */
834 int myindex  = -1;
835 int wearealike = 0;                     /* 2 Kermits have compatible sysids */
836 char * cksysid =                        /* My system ID */
837 #ifdef UNIX
838     "U1"
839 #else
840 #ifdef VMS
841     "D7"
842 #else
843 #ifdef OSK
844     "UD"
845 #else
846 #ifdef AMIGA
847     "L3"
848 #else
849 #ifdef MAC
850     "A3"
851 #else
852 #ifdef OS2
853 #ifdef NT
854     "UN"
855 #else /* NT */
856     "UO"
857 #endif /* NT */
858 #else /* OS2 */
859 #ifdef datageneral
860     "F3"
861 #else
862 #ifdef GEMDOS
863     "K2"
864 #else
865 #ifdef STRATUS
866     "MV"
867 #else
868     ""
869 #endif /* STRATUS */
870 #endif /* GEMDOS */
871 #endif /* datageneral */
872 #endif /* OS2 */
873 #endif /* MAC */
874 #endif /* AMIGA */
875 #endif /* OSK */
876 #endif /* VMS */
877 #endif /* UNIX */
878     ;
879
880 int oopts = -1;                         /* O-Packet Options */
881 int omode = -1;                         /* O-Packet Transfer Mode */
882 int oname = -1;                         /* O-Packet Filename Options */
883 int opath = -1;                         /* O-Packet Pathname Options */
884
885 struct zattr iattr;                     /* Incoming file attributes */
886
887 #ifdef VMS
888 /* VMS labeled file default options - name only. */
889 int lf_opts = LBL_NAM;
890 #else
891 #ifdef OS2
892 /* OS/2 labeled file default options, all attributes but archived. */
893 unsigned long int lf_opts = LBL_EXT|LBL_HID|LBL_RO|LBL_SYS;
894 #else
895 int lf_opts = 0;
896 #endif /* OS2 */
897 #endif /* VMS */
898
899 /* Packet-related variables */
900
901 int pktnum = 0,                         /* Current packet number */
902     sndtyp = 0,                         /* Type of packet just sent */
903     rcvtyp = 0,                         /* Type of packet just received */
904     rsn,                                /* Received packet sequence number */
905     rln,                                /* Received packet length */
906     size,                               /* Current size of output pkt data */
907     osize,                              /* Previous output packet data size */
908     maxsize,                            /* Max size for building data field */
909     spktl = 0,                          /* Length packet being sent */
910     rpktl = 0,                          /* Length of packet just received */
911     pktpaus = 0,                        /* Interpacket pause interval, msec */
912     rprintf,                            /* REMOTE PRINT flag */
913     rmailf,                             /* MAIL flag */
914     xferstat = -1,                      /* Status of last transaction */
915     filestatus = 0;                     /* Status of last file transfer */
916
917 CHAR pktmsgbuf[PKTMSGLEN+1];
918 CHAR *epktmsg = pktmsgbuf;
919
920 #ifdef pdp11
921 int srvcmdlen = MAXRP;                  /* srvcmd buffer length */
922 #else
923 #ifdef DYNAMIC
924 int srvcmdlen = MAXRP;
925 #else
926 int srvcmdlen = 0;
927 #endif /* DYNAMIC */
928 #endif /* pdp11 */
929
930 CHAR
931 #ifdef pdp11
932     srvcmdbuf[MAXRP+4],
933     *srvcmd = srvcmdbuf,
934 #else
935 #ifdef DYNAMIC
936     *srvcmd = (CHAR *)0,                /* Where to decode server command */
937 #else
938     srvcmdbuf[MAXRP+4],
939     *srvcmd = srvcmdbuf,
940 #endif /* DYNAMIC */
941 #endif /* pdp11 */
942     padbuf[96],                         /* Buffer for send-padding */
943     *recpkt,
944     *rdatap,                            /* Pointer to received packet data */
945     *data = (CHAR *)0,                  /* Pointer to send-packet data */
946     *srvptr,                            /* Pointer to srvcmd */
947     mystch = SOH,                       /* Outbound packet-start character */
948     stchr = SOH;                        /* Incoming packet-start character */
949
950 /* File-related variables */
951
952 #ifndef NOMSEND                         /* Multiple SEND */
953 struct filelist * filehead = NULL;      /* SEND list */
954 struct filelist * filetail = NULL;
955 struct filelist * filenext = NULL;
956 int addlist = 0;
957 #endif /* NOMSEND */
958
959 char filnam[CKMAXPATH + 1];             /* Name of current file. */
960 char ofilnam[CKMAXPATH + 1];            /* Original name. */
961
962 int pipesend = 0;                       /* Nonzero if sending from pipe */
963 #ifdef PIPESEND
964 char * sndfilter = NULL;                /* Send and receive filters */
965 char * rcvfilter = NULL;
966 #endif /* PIPESEND */
967
968 char ** sndarray = NULL;                /* SEND /ARRAY pointer and range */
969 #ifndef NOSPL
970 int sndxlo = -1, sndxhi = -1, sndxin = -1;
971 #endif /* NOSPL */
972 #endif /* NOXFER */
973
974 #ifndef NOSERVER
975 int ngetpath = 0;                       /* GET search path */
976 int fromgetpath = 0;
977 char * getpath[MAXGETPATH];
978 char * x_user = NULL;                   /* Server login information */
979 char * x_passwd = NULL;
980 char * x_acct = NULL;
981 #endif /* NOSERVER */
982
983 int x_login = 0;                        /* Login required */
984 int x_logged = 0;                       /* User is logged in */
985
986 extern int timelimit;
987
988 #ifdef CK_LOGIN
989 int logintimo = 300;                    /* Login timeout */
990 char * userfile = NULL;                 /* Forbidden user file */
991 #endif /* CK_LOGIN */
992 #ifdef IKSD
993 char * anonfile = NULL;                 /* Anonymous login init file */
994 char * anonroot = NULL;                 /* Anonymous file-system root */
995 int iks_timo  = 300;                    /* 5 minutes idle timo */
996 int iks_retry = 3;                      /* 3 attempts at login */
997 #endif /* IKSD */
998
999 #ifdef CKSYSLOG
1000 extern VOID zsyslog();
1001 extern int ckxlogging, ckxsyslog;
1002 #endif /* CKSYSLOG */
1003
1004 CK_OFF_T fsize = (CK_OFF_T)0,           /* Size of current file */
1005  sendstart = (CK_OFF_T)0,               /* SEND start position */
1006  calibrate = (CK_OFF_T)0;               /* Nonzero if calibration run */
1007
1008 int nzxopts = 0;                        /* Options for nzxpand() */
1009 int nfils = 0;                          /* Number of files in file group */
1010 int wildena = 1;                        /* Wildcard expansion enabled */
1011 #ifdef UNIX
1012 int wildxpand = 0;                      /* Who expands wildcards, 0=Kermit.. */
1013 #else /* UNIX */
1014 #ifdef STRATUS
1015 int wildxpand = 1;                      /* 1=Shell. */
1016 #endif /* STRATUS */
1017 #endif /* UNIX */
1018 #ifdef UNIXOROSK
1019 int matchdot = 0;                       /* Whether to match dot files */
1020 #else
1021 int matchdot = 1;
1022 #endif /* UNIXOROSK */
1023 int matchfifo = 0;                      /* Whether to match FIFO "files" */
1024 int clfils = 0;                         /* Flag for command-line files */
1025 int stayflg = 0;                        /* Flag for "stay", i.e. "-S" */
1026 int xfinish = 0;                        /* Flag for FINISH = EXIT */
1027 long ztusec = -1L;                      /* Used with ztime() */
1028 long ztmsec = -1L;                      /* Ditto */
1029
1030 /* Communication device / connection variables */
1031
1032 char ttname[TTNAMLEN+1];                /* Name of communication device */
1033
1034 #ifdef MAC
1035 int connected = 0;                      /* True if connected */
1036 int startconnected;                     /* initial state of connected */
1037 #endif /* MAC */
1038
1039 long speed = -1L;                       /* Communication device speed */
1040 int wasclosed = 0;                      /* Connection was just closed */
1041 int whyclosed = WC_REMO;                /* why it was closed */
1042 int qnxportlock = 0;                    /* QNX port locking on/off */
1043
1044 #ifndef CLSONDISC
1045 #define CLSONDISC 0
1046 #endif /* CLSONDISC */
1047
1048 int cxflow[CXT_MAX+1];                  /* See initflow() */
1049
1050 #ifndef NOSHOW
1051 char * floname[] = {                    /* Flow control names */
1052   "none", "xon/xoff", "rts/cts", "dtr/cd", "etx/ack", "string",
1053   "xxx1", "xxx2", "dtr/cts", "keep", "auto"
1054 };
1055 int nfloname = (sizeof(floname) / sizeof(char *));
1056
1057 char * cxname[] = {                     /* Connection type names */
1058   "remote", "direct-serial", "modem", "tcp/ip", "x.25", "decnet",
1059   "lat", "netbios", "named-pipe", "ssh", "pipe"
1060 };
1061 int ncxname = (sizeof(cxname) / sizeof(char *));
1062 #endif /* NOSHOW */
1063
1064 int parity = DEFPAR,                    /* Parity specified, 0,'e','o',etc */
1065     hwparity = 0,                       /* Hardware parity for serial port */
1066     stopbits = -1,                      /* Stop bits for serial port */
1067     clsondisc = CLSONDISC,              /* Serial port close on disconnect */
1068     autopar = 0,                        /* Automatic parity change flag */
1069     sosi = 0,                           /* Shift-In/Out flag */
1070     flow = 0,                           /* Flow control (see initflow()) */
1071     autoflow = 1,                       /* Automatic flow control */
1072     turn = 0,                           /* Line turnaround handshake flag */
1073     turnch = XON,                       /* Line turnaround character */
1074     duplex = 0,                         /* Duplex, full by default */
1075     escape = DFESC,                     /* Escape character for connect */
1076     ckdelay = DDELAY,                   /* Initial delay before sending */
1077     tnlm = 0;                           /* Terminal newline mode */
1078
1079 /* Networks for SET HOST */
1080
1081 #ifdef BIGBUFOK
1082 #define MYHOSTL 1024
1083 #else
1084 #define MYHOSTL 100
1085 #endif /* BIGBUFOK */
1086
1087 char myhost[MYHOSTL];                   /* Local host name */
1088 int network = 0;                        /* Network vs serial connection */
1089 int inserver = 0;                       /* Running as an Internet server */
1090 int isguest = 0;                        /* User is anonymous */
1091 char * clienthost = NULL;               /* Peer host name or address */
1092 int tcp_incoming = 0;                   /* Incoming TCP connection? */
1093
1094 #ifdef NETCONN
1095 #ifdef TCPSOCKET
1096 int nettype = NET_TCPB;                 /* Default network type */
1097 #else
1098 #ifdef SUNX25
1099 int nettype = NET_SX25;
1100 #else
1101 #ifdef IBMX25
1102 int nettype = NET_IX25;
1103 #else
1104 #ifdef HPX25
1105 int nettype = NET_HX25;
1106 #else
1107 #ifdef STRATUSX25
1108 int nettype = NET_VX25;
1109 #else
1110 #ifdef DECNET
1111 int nettype = NET_DEC;
1112 #else
1113 #ifdef SUPERLAT
1114 int nettype = NET_SLAT;
1115 #else
1116 int nettype = NET_NONE;
1117 #endif /* SUPERLAT */
1118 #endif /* DECNET */
1119 #endif /* STRATUSX25 */
1120 #endif /* HPX25 */
1121 #endif /* IBMX25 */
1122 #endif /* SUNX25 */
1123 #endif /* TCPSOCKET */
1124 #else  /* NETCONN */
1125 int nettype = NET_NONE;
1126 #endif /* NETCONN */
1127
1128 #ifdef ANYX25
1129 int revcall = 0;                        /* X.25 reverse call not selected */
1130 int closgr  = -1;                       /* X.25 closed user group  */
1131 int cudata = 0;                         /* X.25 call user data not specified */
1132 char udata[MAXCUDATA];                  /* X.25 call user data */
1133
1134 #ifdef IBMX25
1135 /*
1136   I was unable to find any pre-defined MAX values for x25 addresses - the
1137   addresses that I've seen have been around 10-12 characters 32 is probably
1138   enough, 64 is hopefully safe for everyone.
1139 */
1140     x25addr_t local_nua = {'\0'};       /* local x.25 address */
1141     x25addr_t remote_nua = {'\0'};      /* remote x.25 address */
1142     char x25name[32] = {'\0'};          /* x25 device name, sx25a0 or sx25a1 */
1143     char x25dev[64] =  "/dev/x25pkt";   /* x25 device in /dev */
1144     int x25port = 0;                    /* port used for X.25 - AIX only */
1145 #endif /* IBMX25 */
1146
1147 #ifndef IBMX25
1148 /*
1149   This condition is unrelated to the above IBMX25 condition.
1150   IBM X.25 doesn't have PAD support.
1151 */
1152     CHAR padparms[MAXPADPARMS+1]; /* X.3 parameters */
1153 #endif /* IBMX25 */
1154 #endif /* ANYX25 */
1155
1156 /* Other items */
1157
1158 int isinterrupted = 0;                  /* Used in exception handling */
1159 int what = W_INIT;                      /* What I am doing */
1160 int lastxfer = 0;                       /* Last transfer (send or receive) */
1161
1162 extern int mdmtyp;                      /* Modem (/network) type */
1163
1164 #ifdef NT
1165 extern int StartedFromDialer;
1166 #ifdef NTSIG
1167 extern int TlsIndex;
1168 #endif /* NTSIG */
1169 #ifdef NTASM
1170 unsigned long ESPToRestore;             /* Ditto */
1171 #endif /* NTASM */
1172 #endif /* NT */
1173
1174 #ifdef OS2PM
1175 int os2pm = 0;                          /* OS/2 Presentation Manager flag */
1176 #endif /* OS2PM */
1177
1178 /* Terminal screen size, if known, -1 means unknown. */
1179
1180 #ifdef OS2
1181 #include "ckocon.h"
1182 #ifdef KUI
1183 int tt_rows[VNUM] = {24,24,25,1};       /* Rows (height) */
1184 int tt_cols[VNUM] = {80,80,80,80};      /* Columns (width) */
1185 int cmd_rows = 24, cmd_cols = 80;       /* Command/console screen dimensions */
1186 #else /* KUI */
1187 int tt_rows[VNUM] = {-1,24,25,1};       /* Rows (height) */
1188 int tt_cols[VNUM] = {-1,80,80,80};      /* Columns (width) */
1189 int cmd_rows = -1, cmd_cols = -1;       /* Command/console screen dimensions */
1190 #endif /* KUI */
1191 int k95stdio = 0;                       /* Stdio threads */
1192 int tt_bell = XYB_AUD | XYB_SYS;        /* BELL AUDIBLE (system sounds) */
1193 #else /* OS2 */
1194 int tt_rows = -1;                       /* Rows (height) */
1195 int tt_cols = -1;                       /* Columns (width) */
1196 int cmd_rows = 24, cmd_cols = 80;       /* Command/console screen dimensions */
1197 int tt_bell = XYB_AUD;                  /* BELL ON */
1198 #endif /* OS2 */
1199
1200 int tt_print = 0;                       /* Transparent print disabled */
1201 int tt_escape = 1;                      /* Escaping back is enabled */
1202 int tt_scroll = 1;                      /* Scrolling operations are enabled */
1203
1204 int tn_exit = 0;                        /* Exit on disconnect */
1205
1206 int exitonclose = 0;                    /* Exit on close */
1207 int exithangup = 1;                     /* Hangup on exit */
1208 int haveline = 0;                       /* SET LINE or SET HOST in effect */
1209 int tlevel = -1;                        /* Take-file command level */
1210 int hints = 1;                          /* Whether to give hints */
1211
1212 #ifdef NOLOCAL
1213 int remonly = 1;                        /* Remote-mode-only advisory (-R) */
1214 int nolocal = 1;                        /* Remote-only strictly enforced */
1215 #else
1216 int remonly = 0;
1217 int nolocal = 0;
1218 int cx_status = 0;                      /* CONNECT return status */
1219 #endif /* NOLOCAL */
1220
1221 #ifndef NOSPL
1222 extern int cmdlvl;                      /* Command level */
1223 extern int maclvl;                      /* Macro invocation level */
1224 #endif /* NOSPL */
1225
1226 int protocol  = PROTO_K;                /* File transfer protocol = Kermit */
1227
1228 #ifdef NEWDEFAULTS
1229 int prefixing = PX_CAU;
1230 #else
1231 int prefixing = PX_ALL;
1232 #endif /* NEWDEFAULTS */
1233
1234 extern short ctlp[];                    /* Control-prefix table */
1235
1236 int carrier = CAR_AUT;                  /* Pay attention to carrier signal */
1237 int cdtimo = 0;                         /* Carrier wait timeout */
1238 int xitsta = GOOD_EXIT;                 /* Program exit status */
1239
1240 #ifdef VMS                              /* Default filename collision action */
1241 int fncact = XYFX_X;                    /* REPLACE for VMS */
1242 #else
1243 int fncact = XYFX_B;                    /* BACKUP for everybody else */
1244 #endif /* VMS */
1245
1246 int fncsav = -1;                        /* For saving & restoring the above */
1247 int bgset = -1;                         /* BACKGROUND mode set explicitly */
1248
1249 int cmdint = 1;                         /* Interrupts are allowed */
1250 #ifdef UNIX
1251 int xsuspend = DFSUSP;                  /* Whether SUSPEND command, etc, */
1252 #else                                   /* is to be allowed. */
1253 int xsuspend = 0;
1254 #endif /* UNIX */
1255
1256 /* Statistics variables */
1257
1258 CK_OFF_T
1259     flci,                       /* Characters from line, current file */
1260     flco,                       /* Chars to line, current file  */
1261     tlci,                       /* Chars from line in transaction */
1262     tlco,                       /* Chars to line in transaction */
1263     ffc,                        /* Chars to/from current file */
1264     tfc;                        /* Chars to/from files in transaction */
1265
1266 long filcnt,                    /* Number of files in transaction */
1267     filrej,                     /* Number of files rejected in transaction */
1268     cps = 0L,                   /* Chars/sec last transfer */
1269     peakcps = 0L,               /* Peak chars/sec last transfer */
1270     ccu,                        /* Control chars unprefixed in transaction */
1271     ccp,                        /* Control chars prefixed in transaction */
1272     rptn;                       /* Repeated characters compressed */
1273
1274 int tsecs = 0;                          /* Seconds for transaction */
1275 int fsecs = 0;                          /* Per-file timer */
1276
1277 #ifdef GFTIMER
1278 CKFLOAT
1279   fpfsecs = 0.0,                        /* Floating point per-file timer */
1280   fptsecs = 0.0;                        /* and per-transaction timer */
1281 #endif /* GFTIMER */
1282
1283 /* Flags */
1284
1285 int deblog = 0,                         /* Debug log is open */
1286     debok = 1,                          /* Debug log is not disabled */
1287     debxlen = 54,                       /* Default length for debug strings */
1288     debses = 0,                         /* Flag for DEBUG SESSION */
1289     debtim = 0,                         /* Include timestamp in debug log */
1290     debmsg = 0,                         /* Debug messages on/off */
1291     pktlog = 0,                         /* Flag for packet logging */
1292     seslog = 0,                         /* Session logging */
1293     dialog = 0,                         /* DIAL logging */
1294     tralog = 0,                         /* Transaction logging */
1295     tlogfmt = 1,                        /* Transaction log format (verbose) */
1296     tlogsep = (int)',',                 /* Transaction log field separator */
1297     displa = 0,                         /* File transfer display on/off */
1298     stdouf = 0,                         /* Flag for output to stdout */
1299     stdinf = 0,                         /* Flag for input from stdin */
1300     xflg   = 0,                         /* Flag for X instead of F packet */
1301     hcflg  = 0,                         /* Doing Host command */
1302     dest   = DEST_D,                    /* Destination for packet data */
1303     zchkod = 0,                         /* zchko() should work for dirs too? */
1304     zchkid = 0,                         /* zchki() should work for dirs too? */
1305
1306 /* If you change this, also see struct ptab above... */
1307
1308 #ifdef OS2                              /* Flag for file name conversion */
1309     fncnv  = XYFN_L,                    /* Default is Literal in OS/2, */
1310     f_save = XYFN_L,                    /* (saved copy of same) */
1311 #else
1312     fncnv  = XYFN_C,                    /* elsewhere Convert them */
1313     f_save = XYFN_C,                    /* (ditto) */
1314 #endif /* OS2 */
1315
1316     fnspath = PATH_OFF,                 /* Send file path */
1317     fnrpath = PATH_AUTO,                /* Receive file path */
1318     fackpath = 1,                       /* Send back path in ACK to F */
1319     binary = XYFT_B,                    /* Default file transfer mode */
1320     b_save = XYFT_B,                    /* Saved file mode */
1321     eofmethod = 0,                      /* EOF detection method (length) */
1322
1323 #ifdef OS2
1324     cursor_save = -1,                   /* Cursor state */
1325 #endif /* OS2 */
1326
1327     xfermode = XMODE_A,                 /* Transfer mode, manual or auto */
1328     xfiletype = -1,                     /* Transfer only text (or binary) */
1329     recursive = 0,                      /* Recursive directory traversal */
1330     nolinks   = 2,                      /* Don't follow symbolic links */
1331     skipbup   = 0,                      /* Skip backup files when sending */
1332     sendmode = SM_SEND,                 /* Which type of SEND operation */
1333     slostart  = 1,                      /* Slow start (grow packet lengths) */
1334     cmask  = 0377,                      /* CONNECT (terminal) byte mask */
1335     fmask  = 0377,                      /* File byte mask */
1336     ckwarn = 0,                         /* Flag for file warning */
1337     quiet  = 0,                         /* Be quiet during file transfer */
1338     local  = 0,                         /* 1 = local mode, 0 = remote mode */
1339     cxtype = CXT_REMOTE,                /* Connection type */
1340     server = 0,                         /* Flag for I Am Server */
1341     query = 0,                          /* Flag for Query active */
1342     justone = 0,                        /* Server should do Just One command */
1343     urserver = 0,                       /* Flag for You Are Server */
1344     bye_active = 0,                     /* Flag for BYE command active */
1345     diractive = 0,                      /* Flag for DIRECTORY command active */
1346     cdactive = 0,                       /* Flag for CD command active */
1347     cflg   = 0,                         /* Connect before transaction */
1348     cnflg  = 0,                         /* Connect after transaction */
1349     cxseen = 0,                         /* Flag for cancelling a file */
1350     czseen = 0,                         /* Flag for cancelling file group */
1351     fatalio = 0,                        /* Flag for fatal i/o error */
1352     discard = 0,                        /* Flag for file to be discarded */
1353     keep = SET_AUTO,                    /* Keep incomplete files = AUTO */
1354     unkcs = 1,                          /* Keep file w/unknown character set */
1355 #ifdef VMS
1356     filepeek = 0,                       /* Inspection of files */
1357 #else
1358 #ifdef datgeneral
1359     filepeek = 0,
1360 #else
1361     filepeek = 1,
1362 #endif /* datageneral */
1363 #endif /* VMS */
1364     nakstate = 0,                       /* In a state where we can send NAKs */
1365     dblchar = -1,                       /* Character to double when sending */
1366     moving = 0,                         /* MOVE = send, then delete */
1367     reliable = SET_AUTO,                /* Nonzero if transport is reliable */
1368     xreliable = -1,
1369     setreliable = 0,
1370     urclear = 0,                        /* Nonzero for clear channel to you */
1371     clearrq = SET_AUTO,                 /* SET CLEARCHANEL value */
1372     cleared = 0,
1373     streaming = 0,                      /* Nonzero if streaming is active */
1374     streamok = 0,                       /* Nonzero if streaming negotiated */
1375     streamrq = SET_AUTO,                /* SET STREAMING value */
1376     streamed = -1;                      /* Whether we streamed last time */
1377
1378 char * snd_move = NULL;                 /* Move file after sending it */
1379 char * snd_rename = NULL;               /* Rename file after sending it */
1380 char * rcv_move = NULL;                 /* Move file after receiving it */
1381 char * rcv_rename = NULL;               /* Rename file after receiving it */
1382
1383 char * g_snd_move = NULL;
1384 char * g_snd_rename = NULL;
1385 char * g_rcv_move = NULL;
1386 char * g_rcv_rename = NULL;
1387
1388 #ifdef CK_TRIGGER
1389 char *tt_trigger[TRIGGERS] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
1390 CHAR *tt_trmatch[TRIGGERS] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
1391 char *triggerval = NULL;
1392 #endif /* CK_TRIGGER */
1393
1394 int ckxlogging = 0;                     /* Flag for syslogging active */
1395 int ikdbopen = 0;                       /* Flag for IKSD database active */
1396 int dbinited = 0;                       /* Flag for IKSDB record init'd */
1397 #ifndef CKSYSLOG
1398 int ckxsyslog = 0;                      /* Logging level 0 */
1399 #else
1400 #ifdef SYSLOGLEVEL
1401 int ckxsyslog = SYSLOGLEVEL;            /* Logging level specified */
1402 #else
1403 int ckxsyslog = SYSLG_DF;               /* Default logging level */
1404 #endif /* SYSLOGLEVEL */
1405 #endif /* CKSYSLOG */
1406
1407 #ifndef NOHELP
1408 #ifndef NOCMDL
1409 _PROTOTYP( VOID iniopthlp, (void) );    /* Command-line help initializer */
1410 #endif /* NOCMDL */
1411 #endif /* NOHELP */
1412
1413 _PROTOTYP( VOID getexedir, (void) );
1414 _PROTOTYP( int putnothing, (char) );
1415
1416 #ifdef IKSD
1417 _PROTOTYP( VOID doiksdinit, (void) );
1418 _PROTOTYP( VOID iksdinit, (void) );
1419 _PROTOTYP( VOID doiklog, (void) );
1420 _PROTOTYP( int dbinit, (void) );
1421 #endif /* IKSD */
1422
1423 /* Variables passed from command parser to protocol module */
1424
1425 #ifndef NOSPL
1426 #ifndef NOICP
1427 #ifdef CK_APC
1428 _PROTOTYP( VOID apconect, (void) );
1429 #endif /* CK_APC */
1430 #ifdef OS2
1431 extern int initvik;
1432 #endif /* OS2 */
1433 #endif /* NOICP */
1434 #endif /* NOSPL */
1435 char *clcmds = NULL;                    /* Pointer to command-line commands */
1436
1437 #ifndef NOSETKEY
1438 extern KEY *keymap;
1439 extern MACRO *macrotab;
1440 #endif /* NOSETKEY */
1441
1442 #ifndef NOPUSH
1443 int nopush = 0;                         /* PUSH enabled */
1444 #else
1445 int nopush = 1;                         /* PUSH disabled */
1446 #endif /* NOPUSH */
1447
1448 CHAR sstate  = (CHAR) 0;                /* Starting state for automaton */
1449 CHAR zstate  = (CHAR) 0;                /* For remembering sstate */
1450 char * printername = NULL;              /* NULL if printer not redirected */
1451 int printpipe = 0;                      /* For SET PRINTER */
1452 int noprinter = 0;
1453
1454 #ifndef NOXFER
1455 char *cmarg  = "";                      /* Pointer to command data */
1456 char *cmarg2 = "";                      /* Pointer to 2nd command data */
1457 char **cmlist;                          /* Pointer to file list in argv */
1458
1459 #ifdef CK_AUTODL                        /* Autodownload */
1460 int autodl = 1;                         /* Enabled by default */
1461 #else
1462 int autodl = 0;                         /* (or if not implemented). */
1463 #endif /* CK_AUTODL */
1464 int adl_err = 1;                        /* 1 = stop on error */
1465 #ifdef KUI
1466 int adl_ask = 1;                        /* 1 = file dialog on autodownload */
1467 #else
1468 int adl_ask = 0;                        /* 0 = no file dialog */
1469 #endif /* KUI */
1470 #ifdef OS2                              /* AUTODOWNLOAD parameters */
1471 int adl_kmode = ADL_PACK,               /* Match Packet to signal download */
1472     adl_zmode = ADL_PACK;
1473 char * adl_kstr = NULL;                 /* KERMIT Download String */
1474 char * adl_zstr = NULL;                 /* ZMODEM Download String */
1475 #endif /* OS2 */
1476
1477 int remfile = 0, rempipe = 0, remappd = 0; /* REMOTE output redirection */
1478 char * remdest = NULL;
1479
1480 #ifndef NOSERVER
1481 /*
1482   Server services:
1483    0 = disabled
1484    1 = enabled in local mode
1485    2 = enabled in remote mode
1486    3 = enabled in both local and remote modes
1487   only as initial (default) values.
1488 */
1489 int en_xit = 2;                         /* EXIT */
1490 int en_cwd = 3;                         /* CD/CWD */
1491 int en_cpy = 3;                         /* COPY   */
1492 int en_del = 2;                         /* DELETE */
1493 int en_mkd = 3;                         /* MKDIR */
1494 int en_rmd = 2;                         /* RMDIR */
1495 int en_dir = 3;                         /* DIRECTORY */
1496 int en_fin = 3;                         /* FINISH */
1497 int en_get = 3;                         /* GET */
1498 #ifndef NOPUSH
1499 int en_hos = 2;                         /* HOST enabled */
1500 #else
1501 int en_hos = 0;                         /* HOST disabled */
1502 #endif /* NOPUSH */
1503 int en_ren = 3;                         /* RENAME */
1504 int en_sen = 3;                         /* SEND */
1505 int en_set = 3;                         /* SET */
1506 int en_spa = 3;                         /* SPACE */
1507 int en_typ = 3;                         /* TYPE */
1508 int en_who = 3;                         /* WHO */
1509 #ifdef datageneral
1510 /* Data General AOS/VS can't do this */
1511 int en_bye = 0;                         /* BYE */
1512 #else
1513 int en_bye = 2;                         /* PCs in local mode... */
1514 #endif /* datageneral */
1515 int en_asg = 3;                         /* ASSIGN */
1516 int en_que = 3;                         /* QUERY */
1517 int en_ret = 2;                         /* RETRIEVE */
1518 int en_mai = 3;                         /* MAIL */
1519 int en_pri = 3;                         /* PRINT */
1520 int en_ena = 3;                         /* ENABLE */
1521 #else
1522 int en_xit = 0, en_cwd = 0, en_cpy = 0, en_del = 0, en_mkd = 0, en_rmd = 0,
1523     en_dir = 0, en_fin = 0, en_get = 0, en_hos = 0, en_ren = 0, en_sen = 0,
1524     en_set = 0, en_spa = 0, en_typ = 0, en_who = 0, en_bye = 0, en_asg = 0,
1525     en_que = 0, en_ret = 0, en_mai = 0, en_pri = 0, en_ena = 0;
1526 #endif /* NOSERVER */
1527 #endif /* NOXFER */
1528
1529 /* Miscellaneous */
1530
1531 char **xargv;                           /* Global copies of argv */
1532 int xargc;                              /* and argc  */
1533 int xargs;                              /* an immutable copy of argc */
1534 char *xarg0;                            /* and of argv[0] */
1535 char *pipedata;                         /* Pointer to -P (pipe) data */
1536
1537 extern char *dftty;                     /* Default tty name from ck?tio.c */
1538 extern int dfloc;                       /* Default location: remote/local */
1539 extern int dfprty;                      /* Default parity */
1540 extern int dfflow;                      /* Default flow control */
1541
1542 #ifdef TNCODE
1543 extern int tn_deb;
1544 #endif /* TNCODE */
1545 /*
1546   Buffered file input and output buffers.  See getpkt() in ckcfns.c
1547   and zoutdump() in the system-dependent file i/o module (usually ck?fio.c).
1548 */
1549 #ifndef DYNAMIC
1550 /* Now we allocate them dynamically, see getiobs() below. */
1551 char zinbuffer[INBUFSIZE], zoutbuffer[OBUFSIZE];
1552 #endif /* DYNAMIC */
1553 char *zinptr, *zoutptr;
1554 int zincnt, zoutcnt;
1555 int zobufsize = OBUFSIZE;
1556 int zofbuffer = 1;
1557 int zofblock  = 1;
1558
1559 #ifdef SESLIMIT
1560 int seslimit = 0;
1561 #endif /* SESLIMIT */
1562
1563 #ifdef CK_AUTHENTICATION
1564 #include "ckuath.h"
1565 #endif /* CK_AUTHENTICATION */
1566
1567 _PROTOTYP( int getiobs, (VOID) );
1568
1569 /*  M A I N  --  C-Kermit main program  */
1570
1571 #include <signal.h>
1572
1573 #ifndef NOCCTRAP
1574 #include <setjmp.h>
1575 #include "ckcsig.h"
1576 ckjmpbuf cmjbuf;
1577 #ifdef GEMDOS                           /* Special for Atari ST */
1578 cc_clean();                             /* This can't be right? */
1579 #endif /* GEMDOS */
1580 #endif /* NOCCTRAP */
1581
1582 #ifndef NOXFER
1583 /* Info associated with a system ID */
1584
1585 struct sysdata sysidlist[] = {          /* Add others as needed... */
1586   { "0",  "anonymous",    0, NUL,  0, 0, 0 },
1587   { "A1", "Apple II",     0, NUL,  0, 0, 3 }, /* fix this */
1588   { "A3", "Macintosh",    1, ':',  0, 2, 1 },
1589   { "D7", "VMS",          0, ']',  1, 0, 0 },
1590   { "DA", "RSTS/E",       0, ']',  1, 0, 3 }, /* (i think...) */
1591   { "DB", "RT11",         0, NUL,  1, 0, 3 }, /* (maybe...) */
1592   { "F3", "AOS/VS",       1, ':',  0, 0, 2 },
1593   { "I1", "VM/CMS",       0, NUL,  0, 0, 0 },
1594   { "I2", "MVS/TSO",      0, NUL,  0, 0, 0 },
1595   { "I4", "MUSIC",        0, NUL,  0, 0, 0 },
1596   { "I7", "CICS",         0, NUL,  0, 0, 0 },
1597   { "I9", "MVS/ROSCOE",   0, NUL,  0, 0, 0 },
1598   { "K2", "Atari ST",     1, '\\', 1, 0, 3 },
1599   { "L3", "Amiga",        1, '/',  1, 0, 2 },
1600   { "MV", "Stratus VOS",  1, '>',  0, 1, 0 },
1601   { "N3", "Apollo Aegis", 1, '/',  0, 3, 2 },
1602   { "U1", "UNIX",         1, '/',  0, 3, 2 },
1603   { "U8", "MS-DOS",       1, '\\', 1, 0, 3 },
1604   { "UD", "OS-9",         1, '/',  0, 3, 2 },
1605   { "UN", "Windows-32",   1, '\\', 1, 2, 3 },
1606   { "UO", "OS/2",         1, '\\', 1, 2, 3 }
1607 };
1608 static int nxxsysids = (sizeof(sysidlist) / sizeof(struct sysdata));
1609
1610 /* Given a Kermit system ID code, return the associated name string */
1611 /* and some properties of the filenames... */
1612
1613 char *
1614 getsysid(s) char * s; {                 /* Get system-type name */
1615     int i;
1616     if (!s) return("");
1617     for (i = 0; i < nxxsysids; i++)
1618       if (!strcmp(sysidlist[i].sid_code,s))
1619         return(sysidlist[i].sid_name);
1620     return(s);
1621 }
1622
1623 int
1624 getsysix(s) char *s; {                  /* Get system-type index */
1625     int i;
1626     if (!s) return(-1);
1627     for (i = 0; i < nxxsysids; i++)
1628       if (!strcmp(sysidlist[i].sid_code,s))
1629         return(i);
1630     return(-1);
1631 }
1632 #endif /* NOXFER */
1633
1634 /* Tell if a pathname is absolute (versus relative) */
1635 /* This should be parceled out to each of the ck*fio.c modules... */
1636 /* VMS isabsolute() is now in ckvfio.c. */
1637 #ifndef VMS
1638 int
1639 isabsolute(path) char * path; {
1640     int rc = 0;
1641     int x;
1642     if (!path)
1643       return(0);
1644     if (!*path)
1645       return(0);
1646     x = (int) strlen(path);
1647     debug(F111,"isabsolute",path,x);
1648 #ifdef UNIX
1649     if (*path == '/'
1650 #ifdef DTILDE
1651         || *path == '~'
1652 #endif /* DTILDE */
1653         )
1654       rc = 1;
1655 #else /* def UNIX */
1656 #ifdef OS2
1657     if (*path == '/' || *path == '\\')
1658       rc = 1;
1659     else if (isalpha(*path) && x > 2)
1660       if (*(path+1) == ':' && (*(path +2) == '/' || *(path+2) == '\\'))
1661         rc = 1;
1662 #else /* def OS2 */
1663 #ifdef AMIGA
1664     if (*path == '/'
1665 #ifdef DTILDE
1666         || *path == '~'
1667 #endif /* DTILDE */
1668         )
1669       rc = 1;
1670 #else /* def AMIGA */
1671 #ifdef OSK
1672     if (*path == '/'
1673 #ifdef DTILDE
1674         || *path == '~'
1675 #endif /* DTILDE */
1676         )
1677       rc = 1;
1678 #else /* def OSK */
1679 #ifdef datageneral
1680     if (*path == ':')
1681       rc = 1;
1682 #else /* def datageneral */
1683 #ifdef MAC
1684     rc = 0;                             /* Fill in later... */
1685 #else /* def MAC */
1686 #ifdef STRATUS
1687     rc = 0;                             /* Fill in later... */
1688 #else /* def STRATUS */
1689 #ifdef GEMDOS
1690     if (*path == '/' || *path == '\\')
1691       rc = 1;
1692     else if (isalpha(*path) && x > 1)
1693       if (*(path+1) == ':')
1694         rc = 1;
1695 #endif /* GEMDOS */
1696 #endif /* STRATUS */
1697 #endif /* MAC */
1698 #endif /* datageneral */
1699 #endif /* OSK */
1700 #endif /* AMIGA */
1701 #endif /* OS2 */
1702 #endif /* UNIX */
1703     debug(F101,"isabsolute rc","",rc);
1704     return(rc);
1705 }
1706 #endif /* ndef VMS */
1707
1708 /*  See if I have direct access to the keyboard  */
1709
1710 int
1711 is_a_tty(n) int n; {
1712 #ifdef UNIX
1713     extern int ttfdflg;
1714     if (ttfdflg > 0)
1715       return(1);
1716 #endif /* UNIX */
1717 #ifdef KUI
1718     return 1;
1719 #else /* KUI */
1720 #ifdef NT
1721     if (isWin95())
1722       return(1);
1723     else
1724       return(_isatty(n));
1725 #else
1726 #ifdef IKSD
1727    if (inserver)
1728      return(1);
1729    else
1730 #endif /* IKSD */
1731      return(isatty(n));
1732 #endif /* NT */
1733 #endif /* KUI */
1734 }
1735
1736 #ifndef NOXFER
1737 VOID
1738 initxlist() {
1739     extern char * sndexcept[], * rcvexcept[];
1740     int i;
1741     for (i = 0; i < NSNDEXCEPT; i++) {
1742         sndexcept[i] = NULL;
1743         rcvexcept[i] = NULL;
1744     }
1745 }
1746 #endif /* NOXFER */
1747
1748 /* Initialize flow control table */
1749
1750 VOID
1751 initflow() {                            /* Default values for flow control */
1752 #ifdef VMS                              /* for each kind of connection. */
1753     /* The VMS telnet terminal driver treats "none" as request to lose chars */
1754     cxflow[CXT_REMOTE]  = FLO_XONX;     /* Remote mode... */
1755 #else
1756 #ifdef HPUX
1757     /* Ditto for HP-UX */
1758     cxflow[CXT_REMOTE]  = FLO_XONX;     /* Remote mode... */
1759 #else
1760     /* The temptation is to make this one FLO_KEEP but don't!!! */
1761     /* It totally wrecks binary-file transfer when coming in via Telnet. */
1762     /* In UNIX at least... */
1763     cxflow[CXT_REMOTE]  = FLO_NONE;
1764 #endif /* HPUX */
1765 #endif /* VMS */
1766
1767 #ifdef VMS
1768     cxflow[CXT_DIRECT]  = FLO_XONX;     /* Direct serial connections... */
1769 #else
1770     cxflow[CXT_DIRECT]  = FLO_NONE;
1771 #endif /* VMS */
1772
1773 #ifdef CK_RTSCTS
1774     cxflow[CXT_MODEM]   = FLO_RTSC;     /* Modem connections... */
1775 #else
1776 #ifdef VMS
1777     cxflow[CXT_MODEM]   = FLO_XONX;
1778 #else
1779     cxflow[CXT_MODEM]   = FLO_NONE;
1780 #endif /* VMS */
1781 #endif /* CK_RTSCTS */
1782
1783 #ifdef VMS
1784     cxflow[CXT_TCPIP]   = FLO_XONX;     /* TCP/IP connections... */
1785 #else
1786     cxflow[CXT_TCPIP]   = FLO_NONE;
1787 #endif /* VMS */
1788
1789     cxflow[CXT_SSH]     = FLO_NONE;
1790     cxflow[CXT_X25]     = FLO_NONE;     /* Other kinds of networks... */
1791     cxflow[CXT_DECNET]  = FLO_XONX;
1792     cxflow[CXT_LAT]     = FLO_XONX;
1793     cxflow[CXT_NETBIOS] = FLO_NONE;
1794     cxflow[CXT_NPIPE]   = FLO_NONE;
1795     cxflow[CXT_PIPE]    = FLO_NONE;
1796     flow = cxflow[cxtype];              /* Initial flow setting. */
1797     debug(F101,"initflow","",flow);
1798 }
1799
1800 #ifndef NOXFER
1801 /* Initialize file transfer protocols */
1802
1803 VOID
1804 initproto(y, upbstr, uptstr, srvstr, sndbstr, sndtstr, rcvbstr, rcvtstr)
1805     int y;
1806     char * upbstr, * uptstr, * srvstr, * sndbstr, * sndtstr, * rcvbstr,
1807     * rcvtstr;
1808 /* initproto */ {
1809
1810     if (upbstr)                         /* Convert null strings */
1811       if (!*upbstr)                     /* to null pointers */
1812         upbstr = NULL;
1813
1814     if (uptstr)                         /* Convert null strings */
1815       if (!*uptstr)                     /* to null pointers */
1816         uptstr = NULL;
1817
1818     if (sndbstr)
1819       if (!*sndbstr)
1820         sndbstr = NULL;
1821
1822     if (sndtstr)
1823       if (!*sndtstr)
1824         sndtstr = NULL;
1825
1826     if (rcvbstr)
1827       if (!*rcvbstr)
1828         rcvbstr = NULL;
1829
1830     if (rcvtstr)
1831       if (!*rcvtstr)
1832         rcvtstr = NULL;
1833
1834     if (srvstr)
1835       if (!*srvstr)
1836         srvstr = NULL;
1837
1838     protocol = y;                       /* Set protocol */
1839
1840     if (ptab[protocol].rpktlen > -1)
1841       urpsiz = ptab[protocol].rpktlen;
1842     if (ptab[protocol].spktflg > -1)
1843       spsizf = ptab[protocol].spktflg;
1844     if (ptab[protocol].spktlen > -1) {
1845         spsiz = ptab[protocol].spktlen;
1846         debug(F101,"initproto spsiz","",spsiz);
1847         if (spsizf) {
1848             spsizr = spmax = spsiz;
1849             debug(F101,"initproto spsizr","",spsizr);
1850         }
1851     }
1852     if (ptab[protocol].winsize > -1)
1853       wslotr = ptab[protocol].winsize;
1854     if (ptab[protocol].prefix > -1)
1855       prefixing = ptab[protocol].prefix;
1856     if (ptab[protocol].fnca > -1)
1857       fncact  = ptab[protocol].fnca;
1858     if (ptab[protocol].fncn > -1)
1859       fncnv   = ptab[protocol].fncn;
1860     if (ptab[protocol].fnsp > -1)
1861       fnspath = ptab[protocol].fnsp;
1862     if (ptab[protocol].fnrp > -1)
1863       fnrpath = ptab[protocol].fnrp;
1864
1865     makestr(&(ptab[protocol].h_b_init),upbstr);
1866     makestr(&(ptab[protocol].h_t_init),uptstr);
1867     makestr(&(ptab[protocol].h_x_init),srvstr);
1868     makestr(&(ptab[protocol].p_b_scmd),sndbstr);
1869     makestr(&(ptab[protocol].p_t_scmd),sndtstr);
1870     makestr(&(ptab[protocol].p_b_rcmd),rcvbstr);
1871     makestr(&(ptab[protocol].p_t_rcmd),rcvtstr);
1872 }
1873 #endif /* NOXFER */
1874
1875 #ifndef NOCMDL
1876 VOID
1877 #ifdef CK_ANSIC
1878 docmdline(void * threadinfo)
1879 #else /* CK_ANSIC */
1880 docmdline(threadinfo) VOID * threadinfo;
1881 #endif /* CK_ANSIC */
1882 {
1883 #ifdef NTSIG
1884     setint();
1885     if (threadinfo) {                   /* Thread local storage... */
1886        TlsSetValue(TlsIndex,threadinfo);
1887        debug( F100, "docmdline called with threadinfo block", "", 0 );
1888     } else
1889       debug( F100, "docmdline threadinfo is NULL","",0);
1890 #endif /* NTSIG */
1891 #ifdef CK_LOGIN
1892 #ifdef NT
1893 #ifdef IKSD
1894     if (inserver)
1895       setntcreds();
1896 #endif /* IKSD */
1897 #endif /* NT */
1898 #endif /* CK_LOGIN */
1899     proto();                            /* Take any requested action, then */
1900     if (!quiet)                         /* put cursor back at left margin, */
1901       conoll("");
1902 #ifndef NOLOCAL
1903     if (cnflg) {                        /* Re-connect if requested */
1904         cnflg = 0;
1905         doconect(0,0);
1906         if (ttchk() < 0)
1907           dologend();
1908     }
1909 #endif /* NOLOCAL */
1910
1911 #ifdef NTSIG
1912      ckThreadEnd(threadinfo);
1913 #endif /* NTSIG */
1914    return;
1915 }
1916
1917 void
1918 ikslogin() {
1919     if (sstelnet
1920 #ifdef IKSD
1921         || inserver                     /* Internet server */
1922 #endif /* IKSD */
1923         ) {
1924         char *s;
1925         extern int fdispla;             /* File-transfer display format */
1926         extern char * ikprompt;         /* IKSD prompt */
1927
1928 #ifdef IKSD
1929 #ifdef CK_LOGIN
1930         if (inserver) {
1931             x_login = 1;                /* Login required */
1932             x_logged = 0;               /* Not logged in yet */
1933             cmsetp(ikprompt);           /* Set up IKSD's prompt */
1934 #ifndef NOSERVER
1935             en_mai = 0;                 /* MAIL is disabled */
1936             en_who = 0;                 /* REMOTE WHO is disabled */
1937             en_hos = 0;                 /* REMOTE HOST is disabled */
1938             en_pri = 0;                 /* PRINT is disabled */
1939 #endif /* NOSERVER */
1940         } else {
1941             x_login = 0;                /* Login not required */
1942             x_logged = 1;               /* Already logged in */
1943         }
1944 #endif /* CK_LOGIN */
1945 #endif /* IKSD */
1946         nolocal = 1;                    /* SET LINE/HOST not allowed */
1947         fdispla = XYFD_N;               /* No file-transfer display */
1948 #ifdef NETCONN
1949         clienthost = ckgetpeer();       /* Get client's hostname */
1950         debug(F110,"ikslogin clienthost",clienthost,0);
1951 #endif /* NETCONN */
1952         ztime(&s);                      /* Get current date and time */
1953
1954 #ifdef CK_LOGIN
1955 #ifdef CK_AUTHENTICATION
1956         if (x_login) {
1957             x_logged = ck_tn_auth_valid(); /* Did Telnet Auth succeed? */
1958             debug(F111,"ikslogin","x_logged",x_logged);
1959
1960 #ifdef NT
1961             /* On Windows 9x, we do not have the ability in  */
1962             /* zvuser() at present to determine if the name  */
1963             /* approved in a Kerberos principal is really a  */
1964             /* an account in the Windows Access Control List */
1965             if (isWin95() && x_logged == AUTH_VALID
1966                  && (ck_tn_authenticated() != AUTHTYPE_NTLM)
1967 #ifdef CK_SRP
1968                  && (ck_tn_authenticated() != AUTHTYPE_SRP)
1969 #endif /* CK_SRP */
1970                  ) {
1971                 auth_finished(AUTH_USER);
1972                 x_logged = AUTH_USER;
1973                 printf("WARNING:\r\n");
1974                 printf(
1975 " The Telnet authentication method used cannot provide for automated\r\n");
1976                 printf(
1977 " login to Windows 95 or Windows 98.  A password must be entered\r\n");
1978                 printf(
1979 " locally to validate your userid.  Telnet authentication (and encryption)\r\n"
1980                 );
1981                 printf(
1982 " can be used to validate the host (and protect the privacy of your password.)\
1983 \r\n"
1984                 );
1985             }
1986 #endif /* NT */
1987
1988             if (x_logged == AUTH_VALID) {
1989 #ifdef CK_SSL
1990                 if ((ssl_active_flag || tls_active_flag) &&
1991                     (!TELOPT_U(TELOPT_AUTHENTICATION) ||
1992                      ck_tn_authenticated() == AUTHTYPE_NULL ||
1993                      ck_tn_authenticated() == AUTHTYPE_AUTO)
1994                     ) {
1995 #ifdef SSL_KRB5
1996                     if (tls_is_krb5(0)) {
1997                         printf("Authenticated using Kerberos 5\r\n");
1998 #ifdef CKSYSLOG
1999                         if (ckxsyslog >= SYSLG_LI && ckxlogging) {
2000                             extern char szUserNameAuthenticated[];
2001                             cksyslog(SYSLG_LI, 1, "AUTH_VALID",
2002                                      "Kerberos 5",
2003                                      szUserNameAuthenticated
2004                                      );
2005                         }
2006 #endif /* CKSYSLOG */
2007                     } else
2008 #endif /* SSL_KRB5 */
2009                     {
2010                         printf("Authenticated using X.509 certificate\r\n");
2011 #ifdef CKSYSLOG
2012                         if (ckxsyslog >= SYSLG_LI && ckxlogging) {
2013                             extern char szUserNameAuthenticated[];
2014                             cksyslog(SYSLG_LI, 1, "AUTH_VALID",
2015                                      "X.509 certificate",
2016                                      szUserNameAuthenticated
2017                                      );
2018                         }
2019 #endif /* CKSYSLOG */
2020                     }
2021                 } else
2022 #endif /* CK_SSL */
2023                   {
2024                       printf("Authenticated using %s\r\n",
2025                              AUTHTYPE_NAME(ck_tn_authenticated()));
2026 #ifdef CKSYSLOG
2027                       if (ckxsyslog >= SYSLG_LI && ckxlogging) {
2028                           extern char szUserNameAuthenticated[];
2029                           cksyslog(SYSLG_LI, 1, "AUTH_VALID",
2030                                    AUTHTYPE_NAME(ck_tn_authenticated()),
2031                                    szUserNameAuthenticated
2032                                    );
2033                       }
2034 #endif /* CKSYSLOG */
2035                   }
2036                 zvuser(uidbuf);
2037                 if (zvpass("") == 0)
2038                   x_logged = 0;
2039             } else if (x_logged == AUTH_USER && !strcmp(uidbuf,"anonymous")) {
2040                 extern char szUserNameAuthenticated[];
2041                 zvuser(uidbuf);
2042                 debug(F110,"szUserNameAuthenticated",
2043                       szUserNameAuthenticated,0);
2044                 if (zvpass(szUserNameAuthenticated) == 0) {
2045                   /* Anonymous login failed.  Force a username prompt. */
2046                   x_logged = 0;
2047                   uidbuf[0] = '\0';
2048                 } else {
2049 #ifdef CK_SSL
2050                     if ((ssl_active_flag || tls_active_flag) &&
2051                         (!TELOPT_U(TELOPT_AUTHENTICATION) ||
2052                          ck_tn_authenticated() == AUTHTYPE_NULL ||
2053                          ck_tn_authenticated() == AUTHTYPE_AUTO)) {
2054                         printf("Authenticated using X.509 certificate\r\n");
2055 #ifdef CKSYSLOG
2056                         if (ckxsyslog >= SYSLG_LI && ckxlogging) {
2057                             extern char szUserNameAuthenticated[];
2058                             cksyslog(SYSLG_LI, 1, "AUTH_USER",
2059                                      "X.509 certificate",
2060                                      szUserNameAuthenticated
2061                                      );
2062                         }
2063 #endif /* CKSYSLOG */
2064                     } else
2065 #endif /* CK_SSL */
2066                       {
2067                           printf("Authenticated using %s\r\n",
2068                                  AUTHTYPE_NAME(ck_tn_authenticated())
2069                                  );
2070 #ifdef CKSYSLOG
2071                           if (ckxsyslog >= SYSLG_LI && ckxlogging) {
2072                               cksyslog(SYSLG_LI, 1, "AUTH_USER",
2073                                        AUTHTYPE_NAME(ck_tn_authenticated()),
2074                                        szUserNameAuthenticated
2075                                        );
2076                           }
2077 #endif /* CKSYSLOG */
2078                       }
2079                 }
2080             } else {
2081 #ifdef CKSYSLOG
2082                 if (ckxsyslog >= SYSLG_LI && ckxlogging &&
2083                     x_logged == AUTH_USER) {
2084                     extern char szUserNameAuthenticated[];
2085                     cksyslog(SYSLG_LI, 1, "AUTH_USER",
2086                              AUTHTYPE_NAME(ck_tn_authenticated()),
2087                              szUserNameAuthenticated
2088                              );
2089                 }
2090 #endif /* CKSYSLOG */
2091                 x_logged = 0;
2092                 if (!strcmp("(unknown)",uidbuf)
2093 #ifdef NT
2094                     || !stricmp("administrator",uidbuf)
2095 #ifdef UNIX
2096                     || !strcmp("root",uidbuf)
2097 #else
2098 #ifdef Plan9
2099                     || !strcmp("root",uidbuf)
2100 #else
2101 #ifdef OSK
2102                     || !strcmp("root",uidbuf)
2103 #endif /* OSK */
2104 #endif /* Plan9 */
2105 #endif /* UNIX */
2106 #endif /* NT */
2107                     )
2108                   uidbuf[0] = '\0';
2109             }
2110         }
2111 #endif /* CK_AUTHENTICATION */
2112 #endif /* CK_LOGIN */
2113
2114 #ifdef IKSD
2115         if (inserver)
2116           printf("\r\nInternet Kermit Service ready at %s%s\r\n",s,versio);
2117         else
2118 #endif /* IKSD */
2119           printf("\r\nC-Kermit ready at %s%s\r\n",s,versio);
2120         if (*myhost)
2121           printf("%s\r\n", myhost);
2122         printf("\r\n");
2123     }
2124 #ifdef CK_LOGIN
2125 #ifdef IKSD
2126     if (inserver) {
2127         int i;
2128         extern int arg_x;               /* Flag for '-x' on command line */
2129 #ifndef NOSPL
2130         extern struct mtab *mactab;         /* For ON_LOGIN macro. */
2131         extern int nmac;
2132 #endif /* NOSPL */
2133
2134         debug(F110,"MAIN clienthost",clienthost,0);
2135         srvidl = timelimit = logintimo; /* For interactive login */
2136         rtimer();                       /* Reset timer */
2137         for (i = 0; i < iks_retry && !x_logged; i++) { /* Count retries */
2138             if (gtimer() > logintimo)
2139               break;
2140 #ifdef TNCODE
2141             tn_wait("login loop");
2142             tn_push();
2143 #endif /* TNCODE */
2144             debug(F101,"MAIN LOGIN try","",i);
2145             what = W_NOTHING;           /* Because proto() changes this */
2146
2147 #ifdef IKS_OPTION
2148             debug(F111,"MAIN LOGIN",
2149                   "TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
2150                   TELOPT_SB(TELOPT_KERMIT).kermit.me_start
2151                   );
2152             /* Kermit server negotiated */
2153             if (TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
2154                 debug(F101,"IKSD starting in server mode","",0);
2155                 arg_x = 1;              /* Enter server mode */
2156                 sstate = 'x';
2157 #ifdef IKSDPOPBACK
2158                 justone = 1;            /* Execute one command at a time. */
2159 #endif /* IKSDPOPBACK */
2160                 proto();                /* Enter protocol if requested. */
2161 #ifdef NTSIG
2162                 ck_ih();
2163 #endif /* NTSIG */
2164                 if (x_logged)           /* Logged in */
2165                   break;
2166             } else {                    /* Not in client/server mode */
2167 #endif /* IKS_OPTION */
2168                 debug(F101,"IKSD starting with Username prompt","",0);
2169                 x_logged = ckxlogin((CHAR *)uidbuf,NULL,NULL,1);
2170                 if (sstate) {           /* Received a packet at prompt */
2171 #ifdef IKSDPOPBACK
2172                     justone = 1;        /* Go handle it */
2173 #endif /* IKSDPOPBACK */
2174                     proto();
2175                 }
2176                 if (!x_logged) {        /* In case we are at the prompt... */
2177                     printf("Access denied.\n");
2178                     uidbuf[0] = '\0';   /* Forget the name if we have one */
2179                 }
2180 #ifdef IKS_OPTION
2181             }
2182 #endif /* IKS_OPTION */
2183         }
2184         srvidl = timelimit = iks_timo;  /* Reset command timelimit */
2185         debug(F101,"MAIN LOGIN","",x_logged);
2186         if (!x_logged) {                /* Logins failed. */
2187             if (TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
2188               errpkt((CHAR *)"Login Timeout");
2189             msleep(500);
2190             doexit(BAD_EXIT,0);
2191         }
2192         what = W_NOTHING;               /* Stay in known state */
2193 #ifndef NOSERVER
2194         if (isguest) {
2195             en_pri = 0;                 /* No printing for anonymous users */
2196             en_mai = 0;                 /* No email for anonymous users */
2197             en_mkd = 0;                 /* Or directory creation */
2198             en_rmd = 0;                 /* Or directory removal */
2199             en_ena = 0;                 /* Or ENABLing DISABLEd items */
2200         }
2201 #endif /* NOSERVER */
2202
2203 #ifndef NOSPL
2204 /*
2205   If a macro named "on_login" is defined, execute it.  Also remove it from the
2206   macro table so the user cannot see what it does.  Execute it as part of the
2207   iksd.conf file.
2208 */
2209         if (nmac) {                     /* Any macros defined? */
2210             int k;                      /* Yes */
2211             char * cmd = "on_login";    /* MSVC 2.x compiler error */
2212             k = mlook(mactab,cmd,nmac); /* Look up "on_login" */
2213             if (k >= 0) {               /* If found, */
2214 #ifdef IKSDCONF
2215                 int saved = iksdcf;
2216                 iksdcf = 0;
2217 #endif /* IKSDCONF */
2218                 if (dodo(k,"",0) > -1)  /* set it up, */
2219                   parser(1);            /* execute it */
2220 #ifdef IKSDCONF
2221                 iksdcf = saved;
2222 #endif /* IKSDCONF */
2223                 delmac(cmd,1);          /* and delete it */
2224             }
2225         }
2226 #endif /* NOSPL */
2227     } /* if (inserver) */
2228 #else /* CK_LOGIN */
2229     if (inserver)
2230         srvidl = timelimit = iks_timo;  /* Set idle limits for IKS */
2231 #endif /* CK_LOGIN */
2232 #endif /* IKSD */
2233 }
2234
2235 VOID
2236 #ifdef CK_ANSIC
2237 failcmdline(void * foo)
2238 #else /* CK_ANSIC */
2239 failcmdline(foo) VOID * foo;
2240 #endif /* CK_ANSIC */
2241 {
2242 #ifdef GEMDOS
2243     cc_clean();
2244 #endif /* GEMDOS */
2245 #ifndef NOLOCAL
2246     if (cnflg) doconect(0,0);           /* connect again if requested. */
2247     if (ttchk() < 0)
2248       dologend();
2249 #endif /* NOLOCAL */
2250 }
2251 #endif /* NOCMDL */
2252
2253 #ifndef NOICP
2254 VOID
2255 #ifdef CK_ANSIC
2256 dotakeini(void * threadinfo)            /* Execute init file. */
2257 #else  /* CK_ANSIC */
2258 dotakeini(threadinfo) VOID * threadinfo; /* Execute init file. */
2259 #endif /* CK_ANSIC */
2260 /* dotakeini */ {
2261 #ifdef NTSIG
2262     setint();
2263     if (threadinfo) {                   /* Thread local storage... */
2264        TlsSetValue(TlsIndex,threadinfo);
2265        debug(F100, "dotakeini called with threadinfo block","", 0);
2266     } else
2267       debug(F100, "dotakeini - threadinfo is NULL", "", 0);
2268 #endif /* NTSIG */
2269 #ifdef CK_LOGIN
2270 #ifdef NT
2271 #ifdef IKSD
2272     if (inserver)
2273       setntcreds();
2274 #endif /* IKSD */
2275 #endif /* NT */
2276 #endif /* CK_LOGIN */
2277     cmdini();                           /* Sets tlevel */
2278
2279     debug(F111,"dotakeini","inserver",inserver);
2280     debug(F111,"dotakeini","sstelnet",sstelnet);
2281
2282 #ifdef COMMENT
2283 /* Wrong place for this... */
2284 #ifndef NOXFER
2285 #ifdef CK_FAST
2286     dofast();                           /* By now FAST defaults should be OK */
2287 #endif /* CK_FAST */
2288 #endif /* NOXFER */
2289 #endif /* COMMENT */
2290
2291     doinit();                           /* Now do the initialization file */
2292     debug(F101,"main executing init file","",tlevel);
2293     while (tlevel > -1) {
2294         sstate = (CHAR) parser(1);      /* Execute one command at a time. */
2295         if (sstate) proto();            /* Enter protocol if requested. */
2296 #ifdef NTSIG
2297         ck_ih();
2298 #endif /* NTSIG */
2299     }
2300     debug(F101,"main exits init file","",tlevel);
2301
2302 #ifdef NTSIG
2303     ckThreadEnd(threadinfo);
2304 #endif /* NTSIG */
2305     return;
2306 }
2307
2308 VOID
2309 #ifdef CK_ANSIC
2310 failtakeini(void * threadinfo)
2311 #else /* CK_ANSIC */
2312 failtakeini(threadinfo) VOID * threadinfo;
2313 #endif /* CK_ANSIC */
2314 /* failtakeini */ {
2315 #ifdef GEMDOS
2316     cc_clean();                         /* Atari: Clean up after ^C-trap. */
2317 #endif /* GEMDOS */
2318     fixcmd();
2319     if (!cfilef) {
2320         conoll("Interrupted during initialization or \
2321 command-line processing.");
2322         conoll("C-Kermit quitting...");
2323     }
2324     doexit(BAD_EXIT,-1);                /* Exit with bad status. */
2325 }
2326
2327 VOID
2328 #ifdef CK_ANSIC
2329 doicp(void * threadinfo)
2330 #else /* CK_ANSIC */
2331 doicp(threadinfo) VOID * threadinfo;
2332 #endif /* CK_ANSIC */
2333 /* doicp */ {
2334 #ifdef NTSIG
2335     setint();
2336     if (threadinfo) {                   /* Thread local storage... */
2337        if (!TlsSetValue(TlsIndex,threadinfo))
2338           debug(F101,"doicp TlsSetValue failed","",GetLastError());
2339        debug(F101, "doicp a threadinfo block - TlsIndex", "", TlsIndex);
2340     } else {
2341         debug(F100, "doicp received a null threadinfo", "", 0);
2342     }
2343 #endif /* NTSIG */
2344 #ifdef CK_LOGIN
2345 #ifdef NT
2346 #ifdef IKSD
2347     if (inserver)
2348       setntcreds();
2349 #endif /* IKSD */
2350 #endif /* NT */
2351 #endif /* CK_LOGIN */
2352 #ifdef MAC
2353     while (1) {
2354         extern char *lfiles;            /* Fake pointer cast */
2355
2356         if (connected) {
2357             debug(F100, "doicp: calling macparser", "", 0);
2358             sstate = newparser(1, 1, 0L);
2359
2360             /* ignore null command state */
2361             if (sstate == 'n')
2362               sstate = '\0';
2363
2364             if (sstate)
2365               proto();
2366         } else {
2367             /*
2368              * process take files the finder gave us.
2369              */
2370             if ((tlevel == -1) && lfiles)
2371               startlfile();
2372
2373             debug(F100, "doicp: calling parser", "", 0);
2374             sstate = (CHAR) parser(0);
2375             if (sstate == 'c')          /* if MAC connect */
2376               sstate = 0;
2377             if (sstate)
2378               proto();
2379         }
2380     }
2381 #else /* Not MAC */
2382
2383 #ifndef NOSPL
2384 /*
2385   If interactive commands were given on the command line (using the
2386   -C "command, command, ..." option), assign them to a macro called
2387   "cl_commands", then execute the macro and leave it defined for
2388   subsequent re-execution if desired.
2389 */
2390     if (clcmds) {                       /* Check for -C commands */
2391         int x;
2392         x = addmac("cl_commands",clcmds); /* Put macro in table */
2393         if (x > -1) {                   /* If successful, */
2394             dodo(x,NULL,CF_CMDL);       /* set up for macro execution */
2395             while (maclvl > -1) {       /* Loop getting macro commands. */
2396                 sstate = (CHAR) parser(1);
2397                 if (sstate) proto();    /* Enter protocol if requested. */
2398 #ifdef NTSIG
2399                 ck_ih();
2400 #endif /* NTSIG */
2401             }
2402         }
2403         debug(F100,"doicp calling herald","",0);
2404         herald();
2405     }
2406 #endif /* NOSPL */
2407     while(1) {                          /* Loop getting commands. */
2408         sstate = (CHAR) parser(0);
2409         if (sstate) proto();            /* Enter protocol if requested. */
2410 #ifdef NTSIG
2411        ck_ih();
2412 #endif /* NTSIG */
2413     }
2414 #ifdef NTSIG
2415     ckThreadEnd(threadinfo);
2416 #endif /* NTSIG */
2417 #endif /* MAC */
2418 }
2419
2420 VOID
2421 #ifdef CK_ANSIC
2422 failicp(void * threadinfo)
2423 #else /* CK_ANSIC */
2424 failicp(threadinfo) VOID * threadinfo;
2425 #endif /* CK_ANSIC */
2426 {
2427 #ifdef GEMDOS
2428     cc_clean();
2429 #endif /* GEMDOS */
2430     fixcmd();                           /* Pop command stacks, etc. */
2431     clcmds = NULL;
2432     debug(F100,"ckcmai got interrupt","",0);
2433 }
2434 #endif /* NOICP */
2435
2436 #ifndef NOICP
2437 VOID
2438 #ifdef CK_ANSIC
2439 docmdfile(void * threadinfo)            /* Execute application file */
2440 #else /* CK_ANSIC */
2441 docmdfile(threadinfo) VOID * threadinfo;
2442 #endif /* CK_ANSIC */
2443 /* docmdfile */ {
2444 #ifdef NTSIG
2445     concb((char)escape);
2446     setint();
2447     if (threadinfo) {                   /* Thread local storage... */
2448         TlsSetValue(TlsIndex,threadinfo);
2449         debug(F100, "docmdfile called with threadinfo block","", 0);
2450     } else debug(F100, "docmdfile - threadinfo is NULL", "", 0);
2451 #endif /* NTSIG */
2452 #ifdef CK_LOGIN
2453 #ifdef IKSD
2454 #ifdef NT
2455     if (inserver)
2456       setntcreds();
2457 #endif /* NT */
2458 #endif /* IKSD */
2459 #endif /* CK_LOGIN */
2460     debug(F110,"main cmdfil",cmdfil,0);
2461 #ifndef NOSPL
2462     addmac("\\%0",cmdfil);
2463 #endif /* NOSPL */
2464     dotake(cmdfil);                     /* Set up the command file */
2465     if (tlevel > -1)                    /* Remember we did this */
2466       cfilef = 1;
2467     while (tlevel > -1) {               /* Execute it until it runs out. */
2468         sstate = parser(1);             /* Loop getting commands. */
2469         if (sstate) proto();            /* Enter protocol if requested. */
2470 #ifdef NTSIG
2471         ck_ih();
2472 #endif /* NTSIG */
2473     }
2474
2475 #ifdef NTSIG
2476     ckThreadEnd(threadinfo);
2477 #endif /* NTSIG */
2478     return;
2479 }
2480
2481 VOID
2482 #ifdef CK_ANSIC
2483 failcmdfile(void * threadinfo)
2484 #else /* CK_ANSIC */
2485 failcmdfile(threadinfo) VOID * threadinfo;
2486 #endif /* CK_ANSIC */
2487 /* failcmdfile */ {
2488 #ifdef GEMDOS
2489     cc_clean();                         /* Atari: Clean up after ^C-trap. */
2490 #endif /* GEMDOS */
2491     fixcmd();
2492     if (!cfilef) {
2493         conoll("Interrupted during initialization or \
2494 command-line processing.");
2495         conoll("C-Kermit quitting...");
2496     }
2497     doexit(BAD_EXIT,-1);                /* Exit with bad status. */
2498 }
2499 #endif /* NOICP */
2500
2501 #ifndef NOXFER
2502 VOID
2503 setprefix(z) int z; {                   /* Initial control-char prefixing */
2504 #ifdef CK_SPEED
2505     int i, val;
2506
2507     prefixing = z;
2508     ptab[protocol].prefix = prefixing;
2509     debug(F101,"setprefix","",prefixing);
2510     switch (z) {
2511       case PX_ALL:                      /* All */
2512 #ifdef COMMENT
2513         /* Don't let Clear-Channel be dependent on prefixing */
2514         clearrq = 0;                    /* Turn off clearchannel, fall thru */
2515 #endif /* COMMENT */
2516       case PX_NON:                      /* None */
2517         val = (z == PX_ALL) ? 1 : 0;
2518         for (i =
2519 #ifdef UNPREFIXZERO
2520              0
2521 #else
2522              1
2523 #endif /* UNPREFIXZERO */
2524              ; i < 32; i++)
2525           ctlp[i] = val;
2526         for (i = 127; i < 160; i++) ctlp[i] = val;
2527         ctlp[(unsigned)255] = val;
2528         if (z == PX_NON) {              /* These are never safe */
2529             if (network) {              /* Assume network = telnet or rlogin */
2530                 ctlp[CR] = 1;           /* Prefix CR because of NVT rules */
2531                 ctlp[XON] = ctlp[XOFF] = 1; /* Because of Telnet server */
2532                 ctlp[127] = ctlp[255] = 1;  /* Telnet IAC */
2533                 ctlp[mystch] = ctlp[mystch+128] = 1; /* Kermit packet start */
2534             } else {
2535                 ctlp[CR] = ctlp[255] = ctlp[mystch] = ctlp[mystch+128] = 1;
2536                 if (flow == FLO_XONX)       /* Xon/Xoff forces prefixing */
2537                   ctlp[XON] = ctlp[XOFF] = ctlp[XON+128] = ctlp[XOFF+128] = 1;
2538             }
2539         }
2540         break;
2541
2542       case PX_CAU:                      /* Cautious or Minimal */
2543 #ifdef COMMENT
2544         /* Don't let CLEAR-CHANNEL be dependent on Prefixing */
2545         clearrq = 0;                    /* Turn off clearchannel */
2546 #endif /* COMMENT */
2547       case PX_WIL:                      /* Minimal ("wild") */
2548         ctlp[0] = 1;                    /* Does not include 0 */
2549         for (i = 1; i < 32; i++)
2550           ctlp[i] = 0;
2551         for (i = 127; i < 160; i++)
2552           ctlp[i] = 0;
2553         ctlp[mystch] = ctlp[mystch+128] = 1; /* Kermit start of packet */
2554         if (seol != 13)
2555           ctlp[seol] = ctlp[seol+128] = 1; /* Kermit end */
2556         ctlp[13] = ctlp[141] = 1;       /* In case of TELNET (NVT rules) */
2557         ctlp[(unsigned)255] = 1;        /* Ditto */
2558
2559         /* ^D, ^J, ^M, or ^U followed by tilde trigger Rlogin escape */
2560
2561         ctlp[4]  = ctlp[4+128]  = 1;    /* In case of RLOGIN */
2562         ctlp[10] = ctlp[10+128] = 1;    /* In case of RLOGIN */
2563         ctlp[21] = ctlp[21+128] = 1;    /* In case of RLOGIN */
2564
2565         if (flow == FLO_XONX ||         /* Xon/Xoff forces prefixing these */
2566             prefixing == PX_CAU ||      /* So does CAUTIOUS */
2567             network)                    /* Networks too... */
2568           ctlp[XON] = ctlp[XOFF] = ctlp[XON+128] = ctlp[XOFF+128] = 1;
2569         if (prefixing == PX_CAU) {      /* Cautious - add some more */
2570 #ifdef UNPREFIXZERO
2571             ctlp[0] = 1;
2572 #endif /* UNPREFIXZERO */
2573             ctlp[3]   = ctlp[16]  = 1;             /* ^C, DLE */
2574             ctlp[14]  = ctlp[15]  = 1;             /* SO/SI */
2575             ctlp[24]  = ctlp[25]  = 1;             /* VMS might need these */
2576             ctlp[26]  = ctlp[26+128] = 1;          /* UNIX suspend */
2577             ctlp[28]  = ctlp[29]  = ctlp[30]  = 1; /* Assorted esc chars */
2578             ctlp[131] = ctlp[141] = ctlp[144] = 1; /* and 8-bit versions */
2579             ctlp[(unsigned)255] = ctlp[156] = ctlp[157] = ctlp[158] = 1;
2580         }
2581         break;
2582     }
2583 #endif /* CK_SPEED */
2584 }
2585 #endif /* NOXFER */
2586
2587 VOID
2588 makever() {                             /* Make version string from pieces */
2589     int x, y;
2590     char * s;
2591 #ifndef OS2
2592 #ifndef MAC
2593     ck_s_xver = ck_s_ver;               /* Fill in C-Kermit version number */
2594     ck_l_xver = ck_l_ver;               /* for UNIX, VMS, etc. */
2595 #endif /* MAC */
2596 #endif /* OS2 */
2597     x = strlen(ck_s_name);
2598     y = strlen(ck_s_xver);
2599     if (y + x + 1 < CKVERLEN) {
2600         ckmakmsg(versio,CKVERLEN,ck_s_name," ",ck_s_xver,NULL);
2601     } else {
2602         ckstrncpy(versio,"C-Kermit",CKVERLEN);
2603         return;
2604     }
2605     x += y + 1;
2606   
2607     s = " OPEN SOURCE:";                /* C-Kermit 9.0 and later */
2608     y = strlen(s);
2609     if (CKVERLEN < x + y + 1)
2610       return;
2611     ckstrncat(versio,s,CKVERLEN);
2612
2613     x += y + 1;
2614     if (*ck_s_who) {
2615         y = strlen(ck_s_who);
2616         if (CKVERLEN < x + y + 1)
2617           return;
2618         ckstrncat(versio,"-",CKVERLEN);
2619         ckstrncat(versio,ck_s_who,CKVERLEN);
2620     }
2621     x += y + 1;
2622     y = strlen(ck_s_test);
2623     if (y > 0 && y + x + 1 < CKVERLEN) {
2624         ckstrncat(versio," ",CKVERLEN);
2625         ckstrncat(versio,ck_s_test,CKVERLEN);
2626         x += y + 1;
2627         y = strlen(ck_s_tver);
2628         if (y > 0 && y + x + 1 < CKVERLEN) {
2629             ckstrncat(versio,".",CKVERLEN);
2630             ckstrncat(versio,ck_s_tver,CKVERLEN);
2631             x += y + 1;
2632         }
2633     }
2634     y = strlen(ck_s_date);
2635     if (y > 0 && y + x + 2 < CKVERLEN) {
2636         ckstrncat(versio,", ",CKVERLEN);
2637         ckstrncat(versio,ck_s_date,CKVERLEN);
2638     }
2639     vernum = ck_l_ver;
2640     xvernum = ck_l_xver;
2641     debug(F110,"Kermit version",versio,0);
2642 }
2643
2644 union ck_short shortbytes;              /* For determining byte order */
2645 int byteorder = 0;                      /* 0 = Big Endian; 1 = Little Endian */
2646 int bigendian = 1;
2647 /* NOTE: MUST BE 0 or 1 - nothing else */
2648
2649 #ifndef NOSPL
2650 #define SCRIPTLEN 10240
2651 #endif  /* NOSPL */
2652
2653 #ifdef NETCONN
2654 #ifndef NOCMDL
2655 #ifndef NOURL
2656 VOID
2657 dourl() {
2658     int rc = 0;
2659     char * port = NULL;
2660     extern int ttnproto;
2661     extern struct urldata g_url;
2662
2663 #ifdef COMMENT
2664     /* NOTE: debug() doesn't work yet - must use printf's */
2665     printf("URL:  %s\n",g_url.sav ? g_url.sav : "(none)");
2666     printf("Type: %s\n",g_url.svc ? g_url.svc : "(none)");
2667     printf("User: %s\n",g_url.usr ? g_url.usr : "(none)");
2668     printf("Pass: %s\n",g_url.psw ? g_url.psw : "(none)");
2669     printf("Host: %s\n",g_url.hos ? g_url.hos : "(none)");
2670 /*  printf("Port: %s\n",g_url.por ? g_url.por : "(none)"); */
2671     printf("Path: %s\n",g_url.pth ? g_url.pth : "(none)");
2672 #endif /* COMMENT */
2673
2674     if (!ckstrcmp(g_url.svc,"iksd",-1,0) ||
2675         !ckstrcmp(g_url.svc,"kermit",-1,0)) {
2676         extern char pwbuf[];
2677         extern int pwflg;
2678 #ifdef OS2
2679         extern int pwcrypt;
2680 #endif /* OS2 */
2681
2682         if (!g_url.hos) {
2683             printf("?Incomplete IKSD URL\n");
2684             doexit(BAD_EXIT,1);
2685         }
2686         if (!g_url.usr)
2687             makestr(&g_url.usr,"anonymous");
2688         if (!g_url.psw) {
2689             char * tmpbuf = NULL;
2690             if (!(tmpbuf = (char *)malloc(1024)))
2691                 fatal("dourl: out of memory");
2692             if (!ckstrcmp(g_url.usr,"anonymous",-1,0)) {
2693                 ckmakmsg(tmpbuf,1024,uidbuf,"@",myhost,NULL);
2694                 makestr(&g_url.psw,tmpbuf);
2695             } else {
2696                 readpass(" Password:",tmpbuf,1024);
2697                 makestr(&g_url.psw,tmpbuf);
2698             }
2699             free(tmpbuf);
2700         }
2701         port = "kermit";
2702         ttnproto = NP_TELNET;
2703         nettype = NET_TCPB;
2704         mdmtyp = -nettype;
2705         local = -1;
2706         ckstrncpy(uidbuf,g_url.usr,UIDBUFLEN);
2707         if (g_url.psw) {
2708             ckstrncpy(pwbuf,g_url.psw,PWBUFL);
2709             pwflg = 1;
2710 #ifdef OS2
2711             pwcrypt = 0;
2712 #endif /* OS2 */
2713         }
2714         ckmakmsg(ttname,
2715                  TTNAMLEN,
2716                  g_url.hos,
2717                  ":",
2718                  g_url.por ? g_url.por : port,
2719                  NULL
2720                  );
2721         rc = ttopen(ttname,&local,mdmtyp,0);
2722         if (rc > -1) {
2723             network = 1;
2724             exitonclose = 1;
2725 #ifdef CKLOGDIAL
2726             dolognet();
2727 #endif /* CKLOGDIAL */
2728         } else {
2729             printf("?Connection failed: %s\n",g_url.sav);
2730             doexit(BAD_EXIT,1);
2731         }
2732         /* Also need to check here for secure authentication already done */
2733
2734 #ifdef NOSPL
2735         cflg = 1;
2736 #else
2737         {
2738             char * script = NULL;
2739             if (!(script = (char *)malloc(SCRIPTLEN)))
2740               fatal("dourl: out of memory");
2741             if (!g_url.pth) {           /* Write the appropriate script */
2742                 cflg = 1;
2743                 ckmakxmsg(script,SCRIPTLEN,
2744                           "if not eq {\\v(authstate)} {user} ",
2745                           "if not eq {\\v(authstate)} {valid} { ",
2746                           "remote login ", /* No path */
2747                           g_url.usr,       /* Just log in and CONNECT */
2748                           " ",
2749                           g_url.psw,
2750                           ", if fail exit 1 {IKSD login failed} }",
2751                           ", connect",
2752                           NULL,NULL,NULL,NULL);
2753                 /* printf("CLCMDS 1: %s\n",script); */
2754             } else {
2755                 /* does the path specify a file or a directory? */
2756                 int len = strlen(g_url.pth);
2757                 if (ISDIRSEP(g_url.pth[len-1])) {
2758                     ckmakxmsg(script,SCRIPTLEN, /* Directory name given */
2759                               "if not eq {\\v(authstate)} {user} \
2760 if not eq {\\v(authstate)} {valid} { remote login ",
2761                               g_url.usr,
2762                               " ",
2763                               g_url.psw,
2764                               ", if fail exit 1 {IKSD login failed} }",
2765                               ", set macro error on",
2766                               ", set xfer displ brief",
2767                               ", set xfer bell off",
2768                               ", remote cd ",
2769                               g_url.pth,
2770                               ", lineout directory",
2771                               ", connect"
2772                               );
2773                     /* printf("CLCMDS 2: %s\n",script); */
2774                 } else {
2775                     ckmakxmsg(script,SCRIPTLEN, /* Path given, try to GET */
2776                               "if not eq {\\v(authstate)} {user} \
2777 if not eq {\\v(authstate)} {valid} { remote login ",
2778                               g_url.usr,
2779                               " ",
2780                               g_url.psw,
2781                               ", if fail exit 1 {IKSD login failed} }",
2782                               ", set xfer displ brief",
2783                               ", set xfer bell off",
2784                               ", get ",
2785                               g_url.pth,
2786                               ", .rc := \\v(status)",
2787                               ", if open connection bye",
2788                               ", exit \\m(rc)"
2789                               );
2790                     /* printf("CLCMDS 2: %s\n",script); */
2791                 }
2792             }
2793             clcmds = script;            /* Make this our -C cmdline macro */
2794             /* printf("HAVEURL=%d\n",haveurl); */
2795         }
2796 #endif /* NOSPL */
2797     } else {
2798         if (ckstrcmp(g_url.svc,"telnet",-1,0) &&
2799 #ifdef SSHBUILTIN
2800             ckstrcmp(g_url.svc,"ssh",-1,0) &&
2801 #endif /* SSHBUILTIN */
2802             ckstrcmp(g_url.svc,"ftp",-1,0)) {
2803             printf("?Sorry, %s URLs not supported\n",
2804                    g_url.svc ? g_url.svc : "");
2805             doexit(BAD_EXIT,1);
2806         }
2807     }
2808 }
2809 #endif /* NOCMDL */
2810 #endif /* NETCONN */
2811 #endif /* NOURL */
2812
2813 /*
2814   main()...
2815
2816   If you get complaints about "main: return type is not blah",
2817   define MAINTYPE on the CC command line, e.g. "CFLAGS=-DMAINTYPE=blah"
2818   (where "blah" is int, long, or whatever).
2819
2820   If the complaint is "Attempt to return a value from a function of type void"
2821   then add -DMAINISVOID.
2822 */
2823 #ifndef MAINTYPE
2824 #ifndef MAINISVOID
2825 #define MAINTYPE int
2826 #endif /* MAINISVOID */
2827 #endif /* MAINTYPE */
2828
2829 #ifdef MAINISVOID
2830 #ifndef MAINTYPE
2831 #define MAINTYPE void
2832 #endif /* MAINTYPE */
2833 #endif /* MAINISVOID */
2834
2835 #ifdef aegis
2836 /* On the Apollo, intercept main to insert a cleanup handler */
2837 int
2838 ckcmai(argc,argv) int argc; char **argv;
2839 #else
2840 #ifdef MAC                              /* Macintosh */
2841 int
2842 main (void)
2843 #else
2844 #ifdef __GNUC__                         /* GCC compiler */
2845 int
2846 main(argc,argv) int argc; char **argv;
2847 #else
2848 #ifdef __DECC                           /* DEC Alpha with DEC C compiler */
2849 #ifdef __ALPHA
2850 int
2851 main(argc,argv) int argc; char **argv;
2852 #else                                   /* DEC C compiler, not Alpha */
2853 #define MAINISVOID
2854 VOID
2855 main(argc,argv) int argc; char **argv;
2856 #endif  /* __ALPHA */
2857 #else
2858 #ifdef STRATUS                          /* Stratus VOS */
2859 int
2860 main(argc,argv) int argc; char **argv;
2861 #else                                   /* K-95 */
2862 #ifdef OS2
2863 #ifdef KUI
2864 #define MAINISVOID
2865 void
2866 Main( int argc, char ** argv )
2867 #else /* KUI */
2868 #define MAINISVOID
2869 VOID
2870 main(argc,argv) int argc; char **argv;
2871 #endif /* KUI */
2872 #else  /* Not K95 */
2873 MAINTYPE                                /* All others... */
2874 main(argc,argv) int argc; char **argv;
2875 #endif /* OS2 */
2876 #endif /* STRATUS */
2877 #endif /* __DECC */
2878 #endif /* __GNUC__ */
2879 #endif /* MAC */
2880 #endif /* aegis */
2881
2882 /* main */ {
2883
2884     char *p;
2885
2886 #ifndef NOSETKEY
2887     int i;
2888 #endif /* NOSETKEY */
2889
2890 #ifdef datageneral
2891     short *pfha = 016000000036;         /* Get around LANG_RT problem */
2892     *pfha = (short) 0;                  /* No user protection fault handler */
2893 #endif /* datageneral */
2894
2895     int unbuf = 0;                      /* nonzero for unbuffered stdout */
2896
2897 /* setbuf has to be called on the file descriptor before it is used */
2898
2899 #ifdef UNIX
2900 #ifdef NONOSETBUF                       /* Unbuffered console i/o */
2901     unbuf++;                            /* as a compile-time option */
2902 #endif  /* NONOSETBUF */
2903     if (!unbuf) {                       /* Or as a command-line selection */
2904         int i, n;                       /* We have to pre-pre-scan for */
2905         char * s;                       /* this one. */
2906         for (i = 1; i < argc; i++) {
2907             s = argv[i];
2908             if (!s) n = 0; else n = (int)strlen(s);
2909             if (n > 4) {
2910                 if (!ckstrcmp("--unbuffered",s,n,0)) {
2911                     unbuf++;
2912                     break;
2913                 }
2914             }
2915         }
2916     }
2917     if (unbuf)
2918       setbuf(stdout,NULL);
2919 #endif  /* UNIX */
2920
2921 /* Do some initialization */
2922
2923 #ifdef VMS
2924 #ifdef __DECC
2925     /* Get some RMS default settings. */
2926     get_rms_defaults();
2927 #endif /* def __DECC */
2928 #endif /* def VMS */
2929
2930 #ifndef MAC
2931     xargc = xargs = argc;               /* Make global copies of argc */
2932     xargv = argv;                       /* ...and argv. */
2933     xarg0 = argv[0];
2934 #ifdef NT
2935     setOSVer();
2936 #endif /* NT */
2937     zstrip(argv[0],&p);                 /* Get name we were invoked with */
2938     makestr(&myname,p);
2939     if (!ckstrcmp(myname,"telnet",-1,0))       howcalled = I_AM_TELNET;
2940 #ifdef CK_KERBEROS
2941     else if (!ckstrcmp(myname,"ktelnet",-1,0)) howcalled = I_AM_TELNET;
2942 #endif /* CK_KERBEROS */
2943     else if (!ckstrcmp(myname,"rlogin",-1,0))  howcalled = I_AM_RLOGIN;
2944     else if (!ckstrcmp(myname,"iksd",-1,0))    howcalled = I_AM_IKSD;
2945 #ifdef NEWFTP
2946     else if (!ckstrcmp(myname,"ftp",-1,0))     howcalled = I_AM_FTP;
2947 #endif /* NEWFTP */
2948 #ifndef NOHTTP
2949     else if (!ckstrcmp(myname,"http",-1,0))    howcalled = I_AM_HTTP;
2950 #endif /* NOHTTP */
2951 #ifdef OS2
2952     else if (!ckstrcmp(myname,"telnet.exe",-1,0))  howcalled = I_AM_TELNET;
2953 #ifdef SSHBUILTIN
2954     else if (!ckstrcmp(myname,"ssh",-1,0))  howcalled = I_AM_SSH;
2955     else if (!ckstrcmp(myname,"ssh.exe",-1,0))  howcalled = I_AM_SSH;
2956 #endif /* SSHBUILTIN */
2957 #ifdef CK_KERBEROS
2958     else if (!ckstrcmp(myname,"ktelnet.exe",-1,0)) howcalled = I_AM_TELNET;
2959 #endif /* CK_KERBEROS */
2960     else if (!ckstrcmp(myname,"rlogin.exe",-1,0))  howcalled = I_AM_RLOGIN;
2961 #ifdef NT
2962     else if (!ckstrcmp(myname,"iksdnt",-1,0))    howcalled = I_AM_IKSD;
2963     else if (!ckstrcmp(myname,"iksdnt.exe",-1,0))    howcalled = I_AM_IKSD;
2964 #endif /* NT */
2965 #ifdef NEWFTP
2966     else if (!ckstrcmp(myname,"ftp.exe",-1,0))     howcalled = I_AM_FTP;
2967 #endif /* NEWFTP */
2968 #ifndef NOHTTP
2969     else if (!ckstrcmp(myname,"http.exe",-1,0))    howcalled = I_AM_HTTP;
2970 #endif /* NOHTTP */
2971 #endif /* OS2 */
2972     else if (!ckstrcmp(myname,"kermit-sshsub",-1,0)) howcalled = I_AM_SSHSUB;
2973
2974 #ifndef NOICP
2975     cmdini();                           /* Must come before prescan */
2976     debug(F100,"main cmdini() done","",0);
2977 #endif /* NOICP */
2978     prescan(0);                         /* Pre-Check for debugging, etc */
2979 #endif /* MAC */
2980     debug(F101,"MAIN feol","",feol);
2981     makever();                          /* Put together version strings */
2982 #ifndef NOSETKEY                        /* Allocate & initialize the keymap */
2983     /* This code has been moved to before sysinit() for K95G */
2984     if (!(keymap = (KEY *) malloc(sizeof(KEY)*KMSIZE)))
2985       fatal("main: no memory for keymap");
2986     if (!(macrotab = (MACRO *) malloc(sizeof(MACRO)*KMSIZE)))
2987       fatal("main: no memory for macrotab");
2988     for (i = 0; i < KMSIZE; i++) {
2989        keymap[i] = (KEY) i;
2990        macrotab[i] = NULL;
2991     }
2992 #endif /* NOSETKEY */
2993
2994     shortbytes.x_short = 0xABCD;        /* Get Endianness */
2995     if (shortbytes.x_char[0] == 0xCD) { /* 0 = Big Endian */
2996         byteorder = 1;                  /* 1 = Little Endian */
2997         bigendian = 0;                  /* (for clarity in programming) */
2998     } else {
2999         byteorder = 0;                  /* Big Endian */
3000         bigendian = 1;
3001     }
3002     if (sizeof(CK_OFF_T) == 8)          /* Large files and ints? */
3003       havelfs = 1;
3004
3005     if (sysinit() < 0)                  /* System-dependent initialization. */
3006       fatal("Can't initialize!");
3007     else
3008       initflg = 1;                      /* Remember we did. */
3009     debug(F111,"ckcmai myname",myname,howcalled);
3010
3011 #ifdef UNIX
3012     getexedir();                        /* Compute exedir variable */
3013 #endif /* UNIX */
3014
3015 #ifdef CKSYSLOG
3016 #ifdef SYSLOGLEVEL
3017 /*
3018   If built with -DSYSLOGLEVEL on cc command line, this means we always
3019   do syslogging at the indicated level.
3020 */
3021     zsyslog();                          /* Open syslog */
3022 #else /* SYSLOGLEVEL */
3023 #ifdef IKSD
3024     if (inserver)
3025       zsyslog();                        /* Open syslog */
3026 #endif /* IKSD */
3027 #endif /* SYSLOGLEVEL */
3028 #endif /* CKSYSLOG */
3029
3030 #ifdef CK_KERBEROS
3031     ini_kerb();                         /* Initialize Kerberos data */
3032 #endif /* CK_KERBEROS */
3033 #ifdef CK_SSL
3034     ssl_once_init();
3035 #endif /* CK_SSL */
3036 #ifdef TNCODE
3037     tn_set_modes();                     /* Init Telnet Option tables */
3038 #endif /* TNCODE */
3039
3040 #ifdef CK_TTGWSIZ                       /* Initialize screen dimensions */
3041 #ifdef OS2
3042     ttgcwsz();
3043 #else /* OS2 */
3044     if (ttgwsiz() > 0) {
3045         if (tt_rows > 0 && tt_cols > 0) {
3046             cmd_rows = tt_rows;
3047             cmd_cols = tt_cols;
3048         }
3049     }
3050 #endif /* OS2 */
3051 #endif /* CK_TTGWSIZ */
3052
3053 #ifndef OS2
3054 #ifdef TCPSOCKET
3055 #ifdef CK_SOCKS
3056     SOCKSinit(argv[0]);                 /* Internet relay package... */
3057 #endif /* CK_SOCKS */
3058 #endif /* TCPSOCKET */
3059 #endif /* OS2 */
3060
3061     initflow();                         /* Initialize flow-control table */
3062
3063 #ifndef NOICP
3064 #ifdef CKFLOAT
3065     initfloat();                        /* Deduce floating-point precision */
3066 #endif /* CKFLOAT */
3067 #endif /* NOICP */
3068
3069 #ifndef NOXFER
3070     initxlist();                        /* Init exception lists */
3071
3072 #ifdef CK_XYZ                           /* Initialize protocols...  */
3073
3074 #ifdef XYZ_INTERNAL /* XYZMODEM are internal ... */
3075
3076 #ifdef COMMENT
3077     /* Can't do this for XMODEM because if filename contains a "C" etc... */
3078     initproto(PROTO_X, "rx %s","rx %s", NULL, NULL, NULL, NULL, NULL);
3079     initproto(PROTO_XC,"rc %s","rc %s", NULL, NULL, NULL, NULL, NULL);
3080 #else /* COMMENT */
3081     initproto(PROTO_X, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
3082     initproto(PROTO_XC,NULL, NULL, NULL, NULL, NULL, NULL, NULL);
3083 #endif /* COMMENT */
3084     initproto(PROTO_Y, "rb","rb", NULL, NULL, NULL, NULL, NULL);
3085     initproto(PROTO_G, "rb","rb", NULL, NULL, NULL, NULL, NULL);
3086     initproto(PROTO_Z, "rz","rz", NULL, NULL, NULL, NULL, NULL);
3087    initproto(PROTO_K,"kermit -ir","kermit -r","kermit -x",NULL,NULL,NULL,NULL);
3088     /* Kermit Must be last */
3089
3090 #else /* XYZMODEM are external protocols ... */
3091
3092  /*                  s1      s2     s3    s4      s5         s6      s7     */
3093  initproto(PROTO_X, "rx %s","rx %s",NULL,"sx %s","sx -a %s","rx %s", "rx %s");
3094  initproto(PROTO_XC,"rc %s","rc %s",NULL,"sx %s","sx -a %s","rc %s", "rc %s");
3095  initproto(PROTO_Y, "rb",   "rb",   NULL,"sb %s","sb -a %s","rb",    "rb"   );
3096  initproto(PROTO_G, "rb",   "rb",   NULL,"sb %s","sb -a %s","rb",    "rb"   );
3097  initproto(PROTO_Z, "rz",   "rz",   NULL,"sz %s","sz -a %s","rz",    "rz"   );
3098  initproto(PROTO_K, "kermit -ir","kermit -r","kermit -x",NULL,NULL,NULL,NULL);
3099  /* Kermit must be last */
3100
3101 #endif /* XYZ_INTERNAL */
3102
3103 #else  /* No XYZMODEM support */
3104
3105    initproto(PROTO_K,"kermit -ir","kermit -r","kermit -x",NULL,NULL,NULL,NULL);
3106
3107 #endif /* CK_XYZ */
3108 #endif /* NOXFER */
3109
3110     connoi();                           /* Console interrupts off */
3111
3112 #ifndef NOXFER
3113 #ifdef OS2
3114     /* Initialize Kermit and Zmodem Auto-Download Strings */
3115     adl_kstr = strdup("KERMIT READY TO SEND...");
3116     adl_zstr = strdup("rz\r");
3117 #endif /* OS2 */
3118
3119 #ifdef PATTERNS
3120     initpat();                          /* Initialize filename patterns */
3121 #endif /* PATTERNS */
3122 #endif /* NOXFER */
3123
3124 #ifndef NOCSETS
3125     initcsets();                        /* Initialize character sets */
3126 #endif /* NOCSETS */
3127
3128 #ifndef NOICP
3129 #ifdef DFCDMSG
3130     makestr(&cdmsgstr,DFCDMSG);
3131     makelist(cdmsgstr,cdmsgfile,8);     /* Initialize CD message filenames */
3132 #endif /* DFCDMSG */
3133 #endif /* NOICP */
3134
3135     sstate = 0;                         /* No default start state. */
3136 #ifdef DYNAMIC
3137     if (getiobs() < 0)
3138       fatal("Can't allocate i/o buffers!");
3139 #endif /* DYNAMIC */
3140
3141 #ifndef NOSPL
3142 #ifndef NORANDOM
3143     {
3144         char stackdata[256];
3145         unsigned int c = 1234, n;
3146         /* try to make a random unsigned int to feed srand() */
3147 #ifndef VMS
3148         /* time.h and MultiNet do not get along */
3149         c = time(NULL);
3150 #endif /* VMS */
3151         c *= getpid();
3152         /* Referenced before set... DELIBERATELY */
3153         for (n = 0; n < sizeof(stackdata); n++) /* IGNORE WARNING */
3154           c += stackdata[n];            /* DELIBERATELY USED BEFORE SET */
3155         srand((unsigned int)c);
3156     }
3157 #endif /* NORANDOM */
3158 #endif /* NOSPL */
3159
3160     ckhost(myhost,MYHOSTL);             /* Name of local host */
3161     debug(F110,"main ckhost",myhost,0);
3162 #ifdef IKSD
3163     if (!inserver) {
3164 #endif /* IKSD */
3165         ckstrncpy(ttname,dftty,TTNAMLEN); /* Set up default tty name. */
3166         local = nolocal ? 0 : dfloc;    /* And whether it's local or remote. */
3167         parity = dfprty;                /* Set initial parity, */
3168 #ifndef NOXFER
3169         myindex = getsysix(cksysid);    /* System index */
3170 #endif /* NOXFER */
3171         if (local) if (ttopen(ttname,&local,0,0) < 0) {
3172 #ifndef OS2
3173             conol("Can't open device: ");
3174             conoll(ttname);
3175 #endif /* OS2 */
3176             local = 0;
3177             ckstrncpy(ttname,CTTNAM,TTNAMLEN);
3178         }
3179         setflow();                      /* Set appropriate flow control */
3180         speed = ttgspd();               /* Get transmission speed. */
3181 #ifdef IKSD
3182     }
3183 #endif /* IKSD */
3184
3185 #ifdef ANYX25                           /* All X.25 implementations */
3186 #ifndef IBMX25                          /* except IBM have PAD support */
3187     initpad();                          /* Initialize X.25 PAD */
3188 #endif /* IBMX25 */
3189 #endif /* ANYX25 */
3190
3191 #ifndef NOXFER
3192     if (inibufs(SBSIZ,RBSIZ) < 0)       /* Allocate packet buffers */
3193       fatal("Can't allocate packet buffers!");
3194 #ifndef NOCKSPEED
3195     setprefix(prefixing);               /* Set up control char prefixing */
3196 #endif /* NOCKSPEED */
3197 #endif /* NOXFER */
3198
3199 #ifndef NOICP
3200     if (sstelnet
3201 #ifdef IKSD
3202         || inserver
3203 #endif /* IKSD */
3204         ) {
3205         int on = 1, x = 0;
3206         extern int ckxech, ttnet, ttnproto, cmdmsk;
3207 #ifdef SO_SNDBUF
3208         extern int tcp_sendbuf;
3209 #endif
3210 #ifdef SO_RCVBUF
3211         extern int tcp_recvbuf;
3212 #endif
3213 #ifdef SO_KEEPALIVE
3214         extern int tcp_keepalive;
3215 #endif
3216 #ifdef SO_LINGER
3217         extern int tcp_linger, tcp_linger_tmo;
3218 #endif /* SO_LINGER */
3219 #ifdef SO_DONTROUTE
3220         extern int tcp_dontroute;
3221 #endif /* SO_DONTROUTE */
3222 #ifdef TCP_NODELAY
3223         extern int tcp_nodelay;
3224 #endif /* TCP_NODELAY */
3225 #ifdef IKSD
3226         extern int iklogopen;
3227 #endif /* IKSD */
3228         extern int ttmdm;
3229
3230 #ifdef UNIX
3231         if (isatty(0))
3232           fatal("Internet Kermit Service cannot be started at a terminal.");
3233 #endif /* UNIX */
3234
3235         reliable = xreliable = SET_ON;  /* IKSD has reliable connection */
3236 #ifndef VMS
3237         flow = 0;                       /* No flow control needed */
3238 #endif /* VMS */
3239         bgset = 0;                      /* Not in background */
3240         nopush = 1;                     /* No external processes */
3241         parity = 0;                     /* 8 bits ... */
3242         cmdmsk = 0xff;                  /* all the way */
3243         cmask = 0xff;
3244
3245 #ifdef IKSD
3246         if (inserver) {                 /* If IKSD */
3247             doiksdinit();               /* Execute IKSD configuration file */
3248             while (tlevel > -1)
3249               parser(1);                /* (Ignore any file-xfer commands) */
3250             iksdcf = 1;                 /* IKSD c.f. has been processed */
3251         }
3252         if (!iklogopen) (VOID) doiklog(); /* Open Kermit-specific log */
3253 #endif /* IKSD */
3254
3255 #ifdef UNIX
3256         setbuf(stdout,NULL);            /* Don't buffer the output */
3257         ckstrncpy(ttname,"0",TTNAMLEN); /* not "/dev/tty"... */
3258 #endif /* UNIX */
3259         local = 0;                      /* We are in remote mode */
3260         ckxech = 1;                     /* We will echo */
3261 #ifdef OS2
3262         nettype = NET_TCPB;             /* So ttopen() treats the connection */
3263         mdmtyp = -nettype;              /* as a network */
3264 #endif /* OS2 */
3265         debug(F100,"main about to call ttopen() inserver","",0);
3266         if (ttopen(ttname,&local,mdmtyp,0) < 0) { /* Open comm channel */
3267             fatal("can't initialize i/o");
3268         }
3269 #ifdef OS2
3270         local = 0;
3271         network = 1;                    /* Does use networking code */
3272 #else  /* OS2 */
3273         network = 0;                    /* Does not use networking code */
3274 #endif /* OS2 */
3275         ttmdm = -1;                     /* Does not use a modem */
3276         sstelnet = 1;                   /* Do server-side Telnet negotations */
3277         debug(F111,"MAIN","sstelnet",sstelnet);
3278         ttnet = NET_TCPB;               /* Network type is TCP sockets */
3279         ttnproto = NP_TELNET;           /* Netword protocol is Telnet */
3280 #ifdef IKSDB
3281         dbinit();                       /* Initialize database record */
3282 #endif /* IKSDB */
3283 #ifndef OS2
3284 #ifdef CK_AUTHENTICATION
3285         /* Before initializating Telnet/Rlogin negotiations, init Kerberos */
3286         ck_auth_init(ckgetpeer(),"","",0);
3287 #endif /* CK_AUTHENTICATION */
3288
3289 #ifdef NON_BLOCK_IO
3290         on = 1;
3291         x = socket_ioctl(0,FIONBIO,&on);
3292         debug(F101,"main FIONBIO","",x);
3293 #endif /* NON_BLOCK_IO */
3294 #ifdef SO_OOBINLINE
3295         on = 1;
3296         x = setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on));
3297         debug(F101,"main SO_OOBINLINE","",x);
3298 #endif /* SO_OOBINLINE */
3299
3300 #ifndef NOTCPOPTS
3301 #ifndef datageneral
3302 #ifdef SOL_SOCKET
3303 #ifdef TCP_NODELAY
3304         no_delay(0,tcp_nodelay);
3305 #endif /* TCP_NODELAY */
3306 #ifdef SO_KEEPALIVE
3307         keepalive(0,tcp_keepalive);
3308 #endif /* SO_KEEPALIVE */
3309 #ifdef SO_LINGER
3310         ck_linger(0,tcp_linger, tcp_linger_tmo);
3311 #endif /* SO_LINGER */
3312 #ifdef SO_DONTROUTE
3313         dontroute(0,tcp_dontroute);
3314 #endif /* SO_DONTROUTE */
3315 #ifdef SO_SNDBUF
3316         sendbuf(0,tcp_sendbuf);
3317 #endif /* SO_SNDBUF */
3318 #ifdef SO_RCVBUF
3319         recvbuf(0,tcp_recvbuf);
3320 #endif /* SO_RCVBUF */
3321 #endif /* SOL_SOCKET */
3322 #endif /* datageneral */
3323 #endif /* NOTCPOPTS */
3324
3325 #ifdef CK_SSL
3326         if (ck_ssleay_is_installed()) {
3327             if (!ssl_tn_init(SSL_SERVER)) {
3328                 if (bio_err != NULL) {
3329                     BIO_printf(bio_err,"do_ssleay_init() failed\r\n");
3330                     ERR_print_errors(bio_err);
3331                 } else {
3332                     fflush(stderr);
3333                     fprintf(stderr,"do_ssleay_init() failed\r\n");
3334                     ERR_print_errors_fp(stderr);
3335                 }
3336                 switch (ttnproto) {
3337                   case NP_SSL:
3338                   case NP_TLS:
3339                   case NP_SSL_RAW:
3340                   case NP_TLS_RAW:
3341                   case NP_SSL_TELNET:
3342                   case NP_TLS_TELNET:
3343                     doexit(BAD_EXIT,1);
3344                 }
3345                 /* otherwise we will continue to accept the connection   */
3346                 /* without SSL or TLS support unless required. */
3347                 if ( TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) != TN_NG_MU )
3348                     TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) = TN_NG_RF;
3349                 if ( TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) != TN_NG_MU )
3350                     TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
3351                 if ( TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) != TN_NG_MU )
3352                     TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) = TN_NG_RF;
3353                 if ( TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) != TN_NG_MU )
3354                     TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
3355             } else {
3356                 if ( ck_ssl_incoming(0) < 0 ) {
3357                     doexit(BAD_EXIT,1);
3358                 }
3359             }
3360         }
3361 #endif /* CK_SSL */
3362
3363 #ifdef TNCODE
3364         tn_ini();                       /* Start Telnet negotiation now */
3365 #endif /* TNCODE */
3366 #endif /* OS2 */
3367     }
3368     debug(F101,"main argc after prescan()","",argc);
3369
3370     /* Now process any relevant environment variables */
3371
3372 #ifndef NODIAL
3373     getdialenv();                       /* Dialing */
3374 #ifdef NETCONN
3375     ndinit();                           /* Initialize network directory info */
3376     getnetenv();                        /* Network directories */
3377 #endif /* NETCONN */
3378 #endif /* NODIAL */
3379
3380 #ifndef NOXFER
3381 #ifdef CK_FAST
3382     dofast();                           /* By now FAST defaults should be OK */
3383 #endif /* CK_FAST */
3384 #endif /* NOXFER */
3385
3386 #ifndef NOCMDL
3387     ikslogin();                          /* IKSD Login and other stuff */
3388 #ifdef IKSD
3389 #ifdef NT
3390     if ( inserver )
3391       setntcreds();
3392 #endif /* NT */
3393 #endif /* IKSD */
3394 #endif /* NOCMDL */
3395
3396     if (howcalled == I_AM_SSHSUB) {
3397         reliable = 1;                   /* We say the connection is reliable */
3398         xreliable = 1;                  /* And that we said it was */
3399         setreliable = 1;                /* And pretend the "user" did too */
3400         xfinish = 1;                    /* For REMOTE HELP response */
3401         mdmtyp = 0;                     /* For ttopen() */
3402         ckstrncpy(ttname,"0",TTNAMLEN+1);  /* Use file descriptor 0 */
3403         local = 0;                         /* And force remote mode */
3404         ttopen(ttname,&local,mdmtyp,0); /* Open the "connection" */
3405         sstate = 'x';                   /* Initial state is Server */
3406         proto();                        /* Enter protocol */
3407         doexit(GOOD_EXIT,xitsta);       /* Exit when done */
3408     }
3409     debug(F111,"howcalled",myname,howcalled);
3410
3411 #ifdef NOCCTRAP
3412     dotakeini(0);
3413 #else /* NOCCTRAP */
3414     debug(F100,"main about to cc_execute","",0);
3415     setint();
3416     cc_execute( ckjaddr(cmjbuf), dotakeini, failtakeini );
3417 #endif /* NOCCTRAP */
3418
3419     debug(F111,"main 2 cfilef",cmdfil,cfilef);
3420     if (cmdfil[0]) {                    /* If we got one (see prescan())... */
3421 #ifdef NOCCTRAP
3422         docmdfile(0);                   /* execute it. */
3423 #else /* NOCCTRAP */
3424         setint();
3425         cc_execute( ckjaddr(cmjbuf), docmdfile, failcmdfile );
3426 #endif /* NOCCTRAP */
3427     }
3428 #ifndef OS2                             /* Preserve name so we can delete it */
3429     *cmdfil = '\0';                     /* Done, nullify the file name */
3430 #endif /* OS2 */
3431 #endif /* NOICP */
3432
3433 #ifndef NOCMDL
3434 /* Look for a UNIX-style command line... */
3435
3436     what = W_NOTHING;
3437
3438     debug(F101,"main argc","",argc);
3439 #ifndef NOHELP
3440     iniopthlp();                        /* Initialize cmdline arg help */
3441 #endif /* NOHELP */
3442     if (
3443 #ifdef COMMENT
3444         !cfilef &&
3445 #endif /* COMMENT */
3446         argc > 1) {                     /* Command line arguments? */
3447         sstate = (CHAR) cmdlin();       /* Yes, parse. */
3448 #ifdef NETCONN
3449 #ifndef NOURL
3450         if (haveurl) {                  /* Was a URL given? */
3451             dourl();                    /* if so, do it. */
3452         }
3453 #endif /* NOURL */
3454 #endif /* NETCONN */
3455 #ifndef NOXFER
3456         zstate = sstate;                /* Remember sstate around protocol */
3457         debug(F101,"main zstate","",zstate);
3458 #endif /* NOXFER */
3459
3460 #ifndef NOLOCAL
3461         if (cflg) {                     /* Connect first if requested */
3462             doconect(0,0);
3463             if (ttchk() < 0)
3464               dologend();
3465             cflg = 0;
3466         }
3467 #endif /* NOLOCAL */
3468
3469 #ifndef NOXFER
3470         if (sstate) {
3471 #ifndef NOLOCAL
3472             if (displa) concb((char)escape); /* (for console "interrupts") */
3473 #endif /* NOLOCAL */
3474 #ifdef NOCCTRAP
3475             docmdline(1);
3476 #else /* NOCCTRAP */
3477             setint();
3478             cc_execute( ckjaddr(cmjbuf), docmdline, failcmdline );
3479 #endif /* NOCCTRAP */
3480         }
3481 #endif /* NOXFER */
3482
3483 #ifndef NOICP
3484 /*
3485   If a command-line action argument was given and -S ("stay") was not given,
3486   exit now.
3487 */
3488         if ((cflg || cnflg || zstate) && !stayflg)
3489 #endif /* NOICP */
3490           doexit(GOOD_EXIT,xitsta);     /* Exit with good status */
3491
3492 #ifndef NOLOCAL
3493 #ifndef NOICP
3494         if (local) {
3495 #ifdef NETCONN
3496             if ((cflg || cnflg) && tn_exit && ttchk() < 0)
3497               doexit(GOOD_EXIT,xitsta); /* Exit with good status */
3498 #endif /* NETCONN */
3499             if (exitonclose && !network &&
3500                 (carrier != CAR_OFF && (ttgmdm() & BM_DCD) == 0))
3501               doexit(GOOD_EXIT,xitsta); /* Exit with good status */
3502             if (exitonclose && network && ttchk() < 0)
3503               doexit(GOOD_EXIT,xitsta); /* Exit with good status */
3504         }
3505 #endif /* NOICP */
3506 #endif /* NOLOCAL */
3507     }
3508 #endif /* NOCMDL */
3509
3510 #ifdef NOICP                            /* No interactive command parser */
3511 #ifndef NOCMDL
3512     else {
3513
3514         /* Command-line-only version */
3515         fatal("?No command-line options given - type 'kermit -h' for help");
3516     }
3517 #else                                   /* Neither one! */
3518         sstate = 'x';
3519         justone = 0;
3520         proto();                        /* So go into server mode */
3521         doexit(GOOD_EXIT,xitsta);       /* exit with good status */
3522
3523 #endif /* NOCMDL */
3524 #else /* not NOICP */
3525 /*
3526   If no action requested on command line, or if -S ("stay") was included,
3527   enter the interactive command parser.
3528 */
3529     if (!clcmds)
3530       herald();                         /* Display program herald. */
3531
3532 #ifdef NOCCTRAP
3533     debug(F100,"main NOCCTRAP setting interrupt trap","",0);
3534     setint();                           /* Set up command interrupt traps */
3535     doicp(NULL);
3536 #else /* NOCCTRAP */
3537     while (1) {
3538         debug(F100,"main setting interrupt trap","",0);
3539         setint();                       /* Set up command interrupt traps */
3540         if (!cc_execute(ckjaddr(cmjbuf), doicp, failicp))
3541           break;
3542     }
3543 #endif /* NOCCTRAP */
3544 #endif /* NOICP */
3545 #ifndef MAINISVOID
3546     return(1);
3547 #endif /* MAINISVOID */
3548 }
3549
3550 #ifdef DYNAMIC
3551 /* Allocate file i/o buffers */
3552
3553 char *zinbuffer = NULL, *zoutbuffer = NULL;
3554
3555 int
3556 getiobs() {
3557     zinbuffer = (char *)malloc(INBUFSIZE);
3558     if (!zinbuffer) return(-1);
3559     zoutbuffer = (char *)malloc(zobufsize);
3560     debug(F101,"zoutbuffer malloc","",zobufsize);
3561     if (!zoutbuffer) return(-1);
3562     debug(F100,"getiobs ok","",0);
3563     return(0);
3564 }
3565 #endif /* DYNAMIC */