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