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